package com.iplant.aps.serviceimpl;

import com.iplant.aps.service.AndonService;
import com.iplant.aps.service.mesenum.*;
import com.iplant.aps.service.po.OutResult;
import com.iplant.aps.service.po.ServiceResult;
import com.iplant.aps.service.po.andon.*;
import com.iplant.aps.service.po.aps.APSTaskPart;
import com.iplant.aps.service.po.aps.APSTaskStep;
import com.iplant.aps.service.po.aps.APSTaskStepPlan;
import com.iplant.aps.service.po.bfc.BFCMessage;
import com.iplant.aps.service.po.bms.BMSEmployee;
import com.iplant.aps.service.po.bms.BMSWorkCharge;
import com.iplant.aps.service.po.exc.EXCCallTaskBPM;
import com.iplant.aps.service.po.excel.MyExcelSheet;
import com.iplant.aps.service.po.fmc.FMCWorkCharge;
import com.iplant.aps.service.po.fmc.FMCWorkspace;
import com.iplant.aps.service.po.fpc.FPCPart;
import com.iplant.aps.service.po.lfs.LFSStoreHouse;
import com.iplant.aps.service.po.lfs.LFSWorkAreaStation;
import com.iplant.aps.service.po.ncr.NCRTask;
import com.iplant.aps.service.po.oms.OMSOrder;
import com.iplant.aps.service.po.rro.RROItemTask;
import com.iplant.aps.service.po.rsm.RSMTurnOrderTask;
import com.iplant.aps.service.po.wms.WMSPickDemand;
import com.iplant.aps.service.utils.CalendarUtil;
import com.iplant.aps.service.utils.Configuration;
import com.iplant.aps.service.utils.StringUtils;
import com.iplant.aps.serviceimpl.dao.BaseDAO;
import com.iplant.aps.serviceimpl.dao.andon.AndonConfigDAO;
import com.iplant.aps.serviceimpl.dao.andon.AndonDAO;
import com.iplant.aps.serviceimpl.dao.andon.AndonJournalDAO;
import com.iplant.aps.serviceimpl.dao.andon.AndonJournalItemDAO;
import com.iplant.aps.serviceimpl.dao.aps.APSTaskPartDAO;
import com.iplant.aps.serviceimpl.dao.fmc.FMCWorkspaceDAO;
import com.iplant.aps.serviceimpl.dao.mtc.MTCTaskDAO;
import com.iplant.aps.serviceimpl.dao.oms.OMSOrderDAO;
import com.iplant.aps.serviceimpl.dao.wms.WMSPickDemandDAO;
import com.iplant.aps.serviceimpl.utils.MESServer;
import com.iplant.aps.serviceimpl.utils.aps.APSConstans;
import com.iplant.aps.utils.aps.ExcelUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author PengYouWang
 * 2022-5-24 14:15:59
 */
@Service
public class AndonServiceImpl implements AndonService {

    private static final Logger logger = LoggerFactory.getLogger(AndonServiceImpl.class);

    public AndonServiceImpl() {
    }

    private static AndonService Instance;

    public static AndonService getInstance() {
        if (Instance == null)
            Instance = new AndonServiceImpl();
        return Instance;
    }

    @Override
    public ServiceResult<List<OrderTimeInfo>> Andon_QueryTrainOrderInfoListNew(BMSEmployee wLoginUser) {
        ServiceResult<List<OrderTimeInfo>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            // ①获取有周计划，维修中的订单ID集合
            List<Integer> wIDList = OMSOrderDAO.getInstance().SelectIDListByWeekPlan(wLoginUser, wErrorCode);
            // ①根据订单ID集合，查询维修中的订单
            List<OMSOrder> wOrderList = OMSOrderDAO.getInstance().SelectListByIDList(wLoginUser, wIDList, wErrorCode);

            if (wOrderList == null || wOrderList.size() <= 0) {
                return wResult;
            }

            // 获取车体工位集合
            List<Integer> wBodyStationIDList = AndonDAO.getInstance().Andon_GetBodyStationIDList(wLoginUser,
                    wErrorCode);

            List<Integer> wStationIDList = new ArrayList<>();
            for (OMSOrder wOrder : wOrderList) {
                wStationIDList = AndonDAO.getInstance().QueryCurrentStationList_V2(wLoginUser, wOrder.ID, wErrorCode);
                if (wStationIDList.size() <= 0) {
                    wStationIDList = AndonDAO.getInstance().QueryFirstStationList(wLoginUser, wOrder.ID, wErrorCode);
                }
                for (int wStationID : wStationIDList) {
                    // 不是车体工位直接继续
                    if (wBodyStationIDList.stream().noneMatch(p -> p == wStationID)) {
                        continue;
                    }
                    OrderTimeInfo wInfo = AndonDAO.getInstance().QueryOrderTimeInfo(wLoginUser, wOrder, wStationID,
                            wErrorCode);

                    // 根据订单、工位ID查询落后，提前情况
                    List<APSTaskPart> wTaskPartList = APSTaskPartDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID,
                            -1, -1, wStationID, 1, APSShiftPeriod.Week.getValue(), null, -1, null, null, null,
                            wErrorCode);
                    if (wTaskPartList.size() > 0) {
                        wInfo.PlanStartTime = wTaskPartList.get(0).StartTime;
                        wInfo.PlanEndTime = wTaskPartList.get(0).EndTime;
                        wInfo.PlanEndTime.add(Calendar.HOUR_OF_DAY, -12);

                        wInfo.PlanSituation = CalendarUtil.getDayInterval(wTaskPartList.get(0).StartTime.getTime(),
                                Calendar.getInstance().getTime());

                        SimpleDateFormat wSDF = new SimpleDateFormat("yyyyMMdd");
                        int wShiftID = Integer.parseInt(wSDF.format(wInfo.PlanStartTime.getTime()));
                        int wTShiftID = Integer.parseInt(wSDF.format(Calendar.getInstance().getTime()));

                        switch (wInfo.Status) {
                            case "未开工":
                                if (wShiftID == wTShiftID) {
                                    wInfo.StationColor = 2;
                                } else if (wShiftID > wTShiftID) {
                                    wInfo.StationColor = 3;
                                } else {
                                    wInfo.StationColor = 2;
                                }
                                break;
                            case "工位开工":
                                if (wShiftID >= wTShiftID) {
                                    wInfo.StationColor = 1;
                                } else {
                                    wInfo.StationColor = 2;
                                }
                                break;
                            case "工位完工":
                                wInfo.StationColor = 4;
                                break;
                            case "异常":
                                wInfo.StationColor = 3;
                                break;

                            default:
                                break;
                        }

                    }

                    wResult.Result.add(wInfo);
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<AndonScreen> Andon_QueryAndonScreen(BMSEmployee wLoginUser) {
        ServiceResult<AndonScreen> wResult = new ServiceResult<>();
        wResult.Result = new AndonScreen();
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);

            wResult.Result = AndonDAO.Screen;
            //更新移车单和台位上的车辆、实现快速刷新
            if (wResult.Result != null) {
                wResult.Result.MTCTaskList = MTCTaskDAO.getInstance().SelectList(wLoginUser, null, -1, -1, -1, -1, -1,
                        null,
                        StringUtils.parseListArgs(MTCStatus.Completion.getValue(), MTCStatus.TaskCancel.getValue(),
                                MTCStatus.Default.getValue(), MTCStatus.TaskReject.getValue()),
                        -1, -1, -1, -1, "", wBaseTime, wBaseTime, wErrorCode);
                //查询台位列表
                List<FMCWorkspace> wWorkSpaceList = FMCWorkspaceDAO.getInstance().SelectList(wLoginUser, -1,
                        wErrorCode);

                //清空不展示的车型(线束、管路)
                String wNotDisplayProductChar = Configuration.readConfigString("NotDisplayProductChar", "config" +
                        "/config");
                String[] wCharList = wNotDisplayProductChar.split(",");

                for (AndonWorkspace wAndonWorkspace : wResult.Result.WorkspaceList) {
                    if (wWorkSpaceList.stream().anyMatch(p -> p.ID == wAndonWorkspace.ID)) {
                        wAndonWorkspace.PartNo =
                                wWorkSpaceList.stream().filter(p -> p.ID == wAndonWorkspace.ID).findFirst().get().PartNo;
                    }

                    for (String wChar : wCharList) {
                        if (wAndonWorkspace.PartNo.contains(wChar)) {
                            wAndonWorkspace.PartNo = "";
                            break;
                        }
                    }
                }
                for (FMCWorkspace wFMCWorkspace : wResult.Result.FMCWorkspaceList) {
                    if (wWorkSpaceList.stream().anyMatch(p -> p.ID == wFMCWorkspace.ID)) {
                        wFMCWorkspace.PartNo =
                                wWorkSpaceList.stream().filter(p -> p.ID == wFMCWorkspace.ID).findFirst().get().PartNo;
                    }

                    for (String wChar : wCharList) {
                        if (wFMCWorkspace.PartNo.contains(wChar)) {
                            wFMCWorkspace.PartNo = "";
                            wFMCWorkspace.Status = 0;
                            wFMCWorkspace.ActualPartNoList = new ArrayList<>();
                            break;
                        }
                    }
                }
            }

            if (wResult.Result == null) {
                wResult.Result = new AndonScreen();
            }
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<AndonOrder> Andon_QueryPositionInfo(BMSEmployee wLoginUser, int wOrderID) {
        ServiceResult<AndonOrder> wResult = new ServiceResult<>();
        wResult.Result = new AndonOrder();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            OMSOrder wOrder = OMSOrderDAO.getInstance().SelectByID(wLoginUser, wOrderID, wErrorCode);
            if (wOrder == null || wOrder.ID <= 0) {
                wResult.FaultCode += "提示：参数错误!";
                return wResult;
            }

            List<Integer> wStationIDList = new ArrayList<>();

            // 获取车体工位集合
            List<Integer> wBodyStationIDList = AndonDAO.getInstance().Andon_GetBodyStationIDList(wLoginUser,
                    wErrorCode);

            wStationIDList = AndonDAO.getInstance().QueryCurrentStationList_V2(wLoginUser, wOrder.ID, wErrorCode);
            if (wStationIDList.size() <= 0) {
                wStationIDList = AndonDAO.getInstance().QueryFirstStationList(wLoginUser, wOrder.ID, wErrorCode);
            }

            wStationIDList = wStationIDList.stream()
                    .filter(p -> wBodyStationIDList.stream().anyMatch(q -> q.intValue() == p.intValue()))
                    .collect(Collectors.toList());

            List<OrderTimeInfo> wList = new ArrayList<>();
            for (Integer wStationID : wStationIDList) {
                OrderTimeInfo wInfo = AndonDAO.getInstance().QueryOrderTimeInfo(wLoginUser, wOrder, wStationID,
                        wErrorCode);
                wList.add(wInfo);
            }

            if (wList.size() > 0) {
                wResult.Result.OrderID = wOrderID;
                wResult.Result.PartNo = wOrder.PartNo;
                wResult.Result.PartName = wList.stream().map(p -> p.StationName).collect(Collectors.joining(","));
                wResult.Result.PlaceName = wList.get(0).PlaceName;
                wResult.Result.StockName = wList.get(0).StockName;
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<AndonJournal> Andon_CreateJournal(BMSEmployee wLoginUser) {
        ServiceResult<AndonJournal> wResult = new ServiceResult<>();
        wResult.Result = new AndonJournal();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            int wYear = Calendar.getInstance().get(Calendar.YEAR);
            int wMonth = Calendar.getInstance().get(Calendar.MONTH);
            int wDate = Calendar.getInstance().get(Calendar.DATE);

            // ①今年开始时间
            Calendar wYearStartTime = Calendar.getInstance();
            wYearStartTime.set(wYear, 0, 1, 0, 0, 0);
            // ②今年结束时间
            Calendar wYearEndTime = Calendar.getInstance();
            wYearEndTime.set(wYear, 11, 31, 23, 59, 59);
            // ③本月开始时间
            Calendar wMonthStartTime = Calendar.getInstance();
            wMonthStartTime.set(wYear, wMonth, 1, 0, 0, 0);
            // ④本月结束时间
            Calendar wMonthEndTime = Calendar.getInstance();
            wMonthEndTime.set(wYear, wMonth + 1, 1, 23, 59, 59);
            wMonthEndTime.add(Calendar.DATE, -1);

            // ⑤查询第一部分报表日志
            wResult.Result = AndonJournalDAO.getInstance().QeuryFirstPart_Journal(wLoginUser, wYearStartTime,
                    wYearEndTime, wMonthStartTime, wMonthEndTime, wErrorCode);
            // ⑥查询第三部分报表日志

            // ①次月开始时间
            Calendar wNextMonthStartTime = Calendar.getInstance();
            wNextMonthStartTime.set(wYear, wMonth + 1, 1, 0, 0, 0);
            // ②次月结束时间
            Calendar wNextMonthEndTime = Calendar.getInstance();
            wNextMonthEndTime.set(wYear, wMonth + 2, 1, 23, 59, 59);
            wNextMonthEndTime.add(Calendar.DATE, -1);
            // ③今日开始时间
            Calendar wTodayStartTime = Calendar.getInstance();
            wTodayStartTime.set(wYear, wMonth, wDate, 0, 0, 0);
            // ④今日结束时间
            Calendar wTodayEndTime = Calendar.getInstance();
            wTodayEndTime.set(wYear, wMonth, wDate, 23, 59, 59);

            // ①根据修程获取工位列表
            int wLineID = 1;
            List<Integer> wPartIDList = AndonJournalDAO.getInstance().QueryPartIDListByLineID(wLoginUser, wLineID,
                    wErrorCode);
            // ②获取C5修的工位统计数据
            List<AndonJournalItem> wItemList_C5 = new ArrayList<>();
            for (Integer wPartID : wPartIDList) {
                AndonJournalItem wItem = AndonJournalItemDAO.getInstance().SelectItemByPartIDAndLineID(wLoginUser,
                        wPartID, wLineID, wMonthStartTime, wMonthEndTime, wNextMonthStartTime, wNextMonthEndTime,
                        wTodayStartTime, wTodayEndTime, wErrorCode);
                wItemList_C5.add(wItem);
            }
            // ③获取C6修的工位统计数据
            wLineID = 2;
            wPartIDList = AndonJournalDAO.getInstance().QueryPartIDListByLineID(wLoginUser, wLineID, wErrorCode);
            List<AndonJournalItem> wItemList_C6 = new ArrayList<>();
            for (Integer wPartID : wPartIDList) {
                AndonJournalItem wItem = AndonJournalItemDAO.getInstance().SelectItemByPartIDAndLineID(wLoginUser,
                        wPartID, wLineID, wMonthStartTime, wMonthEndTime, wNextMonthStartTime, wNextMonthEndTime,
                        wTodayStartTime, wTodayEndTime, wErrorCode);
                wItemList_C6.add(wItem);
            }
            // ④添加进返回结果
            wResult.Result.ItemList_C5 = wItemList_C5;
            wResult.Result.ItemList_C6 = wItemList_C6;

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> Andon_SubmitJournal(BMSEmployee wLoginUser, AndonJournal wAndonJournal) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // ①提交父项
            wAndonJournal.CreateID = wLoginUser.ID;
            wAndonJournal.CreateTime = Calendar.getInstance();
            wResult.Result = AndonJournalDAO.getInstance().Update(wLoginUser, wAndonJournal, wErrorCode);
            // ②提交子项
            for (AndonJournalItem wAndonJournalItem : wAndonJournal.ItemList_C5) {
                wAndonJournalItem.ID = 0;
                wAndonJournalItem.ParentID = wResult.Result;
                wAndonJournalItem.LineID = 1;
                AndonJournalItemDAO.getInstance().Update(wLoginUser, wAndonJournalItem, wErrorCode);
            }
            for (AndonJournalItem wAndonJournalItem : wAndonJournal.ItemList_C6) {
                wAndonJournalItem.ID = 0;
                wAndonJournalItem.ParentID = wResult.Result;
                wAndonJournalItem.LineID = 2;
                AndonJournalItemDAO.getInstance().Update(wLoginUser, wAndonJournalItem, wErrorCode);
            }

            // ①获取登陆者的上级
            BMSEmployee wUser = APSConstans.GetBMSEmployee(wLoginUser.ID);
            if (wUser.SuperiorID > 0) {
                // ②发送日志消息给此上级
                List<BFCMessage> wBFCMessageList = new ArrayList<>();
                BFCMessage wMessage = null;
                int wShiftID = MESServer.MES_QueryShiftID(wLoginUser.CompanyID, Calendar.getInstance(),
                        APSShiftPeriod.Day, FMCShiftLevel.Day, 0);
                // 发送任务消息到人员
                wMessage = new BFCMessage();
                wMessage.Active = 0;
                wMessage.CompanyID = 0;
                wMessage.CreateTime = Calendar.getInstance();
                wMessage.EditTime = Calendar.getInstance();
                wMessage.ID = 0;
                wMessage.MessageID = wResult.Result;
                wMessage.Title = StringUtils.Format("{0} {1} {2}", BPMEventModule.ProductionLog.getLable(),
                        wLoginUser.Name, String.valueOf(wShiftID));
                wMessage.MessageText = StringUtils.Format("【{0}】 {1}提交了今日日志，请查阅。",
                        BPMEventModule.ProductionLog.getLable(), wLoginUser.Name);
                wMessage.ModuleID = BPMEventModule.ProductionLog.getValue();
                wMessage.ResponsorID = wUser.SuperiorID;
                wMessage.ShiftID = wShiftID;
                wMessage.StationID = 0;
                wMessage.Type = BFCMessageType.Notify.getValue();
                wBFCMessageList.add(wMessage);

                CoreServiceImpl.getInstance().BFC_UpdateMessageList(wLoginUser, wBFCMessageList);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<AndonJournal> Andon_QueryJournalInfo(BMSEmployee wLoginUser, int wID) {
        ServiceResult<AndonJournal> wResult = new ServiceResult<>();
        wResult.Result = new AndonJournal();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = AndonJournalDAO.getInstance().SelectByID(wLoginUser, wID, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<AndonJournal>> Andon_QueryJournalEmployeeAll(BMSEmployee wLoginUser, Calendar wStartTime,
                                                                           Calendar wEndTime) {
        ServiceResult<List<AndonJournal>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            wResult.Result = AndonJournalDAO.getInstance().SelectList(wLoginUser, -1, wLoginUser.ID, wStartTime,
                    wEndTime, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> Andon_UpdateConfig(BMSEmployee wLoginUser, AndonConfig wAndonConfig) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = AndonConfigDAO.getInstance().Update(wLoginUser, wAndonConfig, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<AndonConfig>> Andon_QueryConfigList(BMSEmployee wLoginUser, int wID) {
        ServiceResult<List<AndonConfig>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            wResult.Result = AndonConfigDAO.getInstance().SelectList(wLoginUser, wID, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<AndonConfig> Andon_QueryConfig(BMSEmployee wLoginUser, int wID) {
        ServiceResult<AndonConfig> wResult = new ServiceResult<>();
        wResult.Result = new AndonConfig();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = AndonConfigDAO.getInstance().SelectByID(wLoginUser, wID, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    private Calendar RefreshProductionStatusTime = Calendar.getInstance();

    private final AndonLocomotiveProductionStatus mAndonLocomotiveProductionStatus =
            new AndonLocomotiveProductionStatus();

    public synchronized AndonLocomotiveProductionStatus GetAndonLocomotiveProductionStatus() {
        try {
            if (mAndonLocomotiveProductionStatus.JHJF_Month <= 0 || RefreshProductionStatusTime.compareTo(Calendar.getInstance()) < 0) {
                // ①查询看板配置
                OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
                List<AndonConfig> wConfigList = AndonConfigDAO.getInstance().SelectList(BaseDAO.SysAdmin, -1,
                        wErrorCode);
                if (wConfigList == null || wConfigList.size() <= 0) {
                    return mAndonLocomotiveProductionStatus;
                }
                AndonConfig wConfig = wConfigList.get(0);
                // ②赋值停时
                AsignStopTimes(BaseDAO.SysAdmin, wConfig, mAndonLocomotiveProductionStatus);
                // ③赋值当月过程返工件数
                AsignRepairs(BaseDAO.SysAdmin, wConfig, mAndonLocomotiveProductionStatus);
                // ④赋值全年统计数据
                AsignStatisticalData(BaseDAO.SysAdmin, wConfig, mAndonLocomotiveProductionStatus);
                // ⑤赋值视频地址和播放类型
                AsignUri(wConfig, mAndonLocomotiveProductionStatus);
                // ⑥赋值工区生产进度
                AsignAreaProgress(BaseDAO.SysAdmin, wConfig, mAndonLocomotiveProductionStatus);
                // ⑦赋值不合格单，异常情况
                AsingNcrAndExc(BaseDAO.SysAdmin, wConfig, mAndonLocomotiveProductionStatus);
                // ⑧赋值零公里得分
                AsignGrade(BaseDAO.SysAdmin, wConfig, mAndonLocomotiveProductionStatus);

                RefreshProductionStatusTime = Calendar.getInstance();
                RefreshProductionStatusTime.add(Calendar.MINUTE, 3);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return mAndonLocomotiveProductionStatus;
    }

    @Override
    public ServiceResult<AndonLocomotiveProductionStatus> Andon_QueryProductionStatus(BMSEmployee wLoginUser) {
        ServiceResult<AndonLocomotiveProductionStatus> wResult = new ServiceResult<>();
        wResult.Result = new AndonLocomotiveProductionStatus();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = GetAndonLocomotiveProductionStatus();

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 赋值零公里得分
     */
    private void AsignGrade(BMSEmployee wLoginUser, AndonConfig wConfig, AndonLocomotiveProductionStatus result) {
        try {
            if (wConfig.GradeFlag == 1) {

                result.Grade_1 = wConfig.Grade_1;
                result.Grade_2 = wConfig.Grade_2;
                result.Grade_3 = wConfig.Grade_3;
                result.Grade_4 = wConfig.Grade_4;
                result.Grade_5 = wConfig.Grade_5;
                result.Grade_6 = wConfig.Grade_6;
                result.Grade_7 = wConfig.Grade_7;
                result.Grade_8 = wConfig.Grade_8;
                result.Grade_9 = wConfig.Grade_9;
                result.Grade_10 = wConfig.Grade_10;
                result.Grade_11 = wConfig.Grade_11;
                result.Grade_12 = wConfig.Grade_12;
                result.Grade_Quality = wConfig.Grade_Quality;
                result.GradeFlag = wConfig.GradeFlag;

                List<Integer> wList = new ArrayList<>(Arrays.asList(result.Grade_1, result.Grade_2,
                        result.Grade_3, result.Grade_4, result.Grade_5, result.Grade_6, result.Grade_7, result.Grade_8,
                        result.Grade_9, result.Grade_10, result.Grade_11, result.Grade_12));
                int wFlag = -1;
                for (int i = wList.size() - 1; i >= 0; i--) {
                    if (wList.get(i) > 0) {
                        wFlag = i;
                        break;
                    }
                }
                result.GradeList = new ArrayList<>();
                for (int i = 0; i <= wFlag; i++) {
                    result.GradeList.add(wList.get(i));
                }
            } else {
                // ①调用focas接口获取数据
                Calendar wTime = Calendar.getInstance();
                int wYear = wTime.get(Calendar.YEAR);
                List<FocasLGL> wLGLList = MyHelperServiceImpl.getInstance().Focas_LGLMES(wLoginUser, wYear);
                // ②赋值result
                AsignResultLGL(wLGLList, result);
                // ③0数据处理
                result.Grade_Quality = wConfig.Grade_Quality;
                result.GradeFlag = 0;

                List<Integer> wList = new ArrayList<>(Arrays.asList(result.Grade_1, result.Grade_2,
                        result.Grade_3, result.Grade_4, result.Grade_5, result.Grade_6, result.Grade_7, result.Grade_8,
                        result.Grade_9, result.Grade_10, result.Grade_11, result.Grade_12));
                int wFlag = -1;
                for (int i = wList.size() - 1; i >= 0; i--) {
                    if (wList.get(i) > 0) {
                        wFlag = i;
                        break;
                    }
                }
                result.GradeList = new ArrayList<>();
                for (int i = 0; i <= wFlag; i++) {
                    result.GradeList.add(wList.get(i));
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 零公里得分赋值(focas数据源)
     */
    private void AsignResultLGL(List<FocasLGL> wLGLList, AndonLocomotiveProductionStatus result) {
        try {
            if (wLGLList == null || wLGLList.size() <= 0)
                return;
            // ①1月份
            if (wLGLList.stream().anyMatch(p -> p.month.equals("1")))
                result.Grade_1 = Integer
                        .parseInt(wLGLList.stream().filter(p -> p.month.equals("1")).findFirst().get().lgl);
            // ②2月份
            if (wLGLList.stream().anyMatch(p -> p.month.equals("2")))
                result.Grade_2 = Integer
                        .parseInt(wLGLList.stream().filter(p -> p.month.equals("2")).findFirst().get().lgl);
            // ③3月份
            if (wLGLList.stream().anyMatch(p -> p.month.equals("3")))
                result.Grade_3 = Integer
                        .parseInt(wLGLList.stream().filter(p -> p.month.equals("3")).findFirst().get().lgl);
            // ④4月份
            if (wLGLList.stream().anyMatch(p -> p.month.equals("4")))
                result.Grade_4 = Integer
                        .parseInt(wLGLList.stream().filter(p -> p.month.equals("4")).findFirst().get().lgl);
            // ⑤5月份
            if (wLGLList.stream().anyMatch(p -> p.month.equals("5")))
                result.Grade_5 = Integer
                        .parseInt(wLGLList.stream().filter(p -> p.month.equals("5")).findFirst().get().lgl);
            // ⑥6月份
            if (wLGLList.stream().anyMatch(p -> p.month.equals("6")))
                result.Grade_6 = Integer
                        .parseInt(wLGLList.stream().filter(p -> p.month.equals("6")).findFirst().get().lgl);
            // ⑦7月份
            if (wLGLList.stream().anyMatch(p -> p.month.equals("7")))
                result.Grade_7 = Integer
                        .parseInt(wLGLList.stream().filter(p -> p.month.equals("7")).findFirst().get().lgl);
            // ⑧8月份
            if (wLGLList.stream().anyMatch(p -> p.month.equals("8")))
                result.Grade_8 = Integer
                        .parseInt(wLGLList.stream().filter(p -> p.month.equals("8")).findFirst().get().lgl);
            // ⑨9月份
            if (wLGLList.stream().anyMatch(p -> p.month.equals("9")))
                result.Grade_9 = Integer
                        .parseInt(wLGLList.stream().filter(p -> p.month.equals("9")).findFirst().get().lgl);
            // ⑩10月份
            if (wLGLList.stream().anyMatch(p -> p.month.equals("10")))
                result.Grade_10 = Integer
                        .parseInt(wLGLList.stream().filter(p -> p.month.equals("10")).findFirst().get().lgl);
            // ⑩11月份
            if (wLGLList.stream().anyMatch(p -> p.month.equals("11")))
                result.Grade_11 = Integer
                        .parseInt(wLGLList.stream().filter(p -> p.month.equals("11")).findFirst().get().lgl);
            // ⑩12月份
            if (wLGLList.stream().anyMatch(p -> p.month.equals("12")))
                result.Grade_12 = Integer
                        .parseInt(wLGLList.stream().filter(p -> p.month.equals("12")).findFirst().get().lgl);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 赋值当月过程返工件数
     */
    private void AsignRepairs(BMSEmployee wLoginUser, AndonConfig wConfig, AndonLocomotiveProductionStatus result) {
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            result.FGJS_One_ZB = wConfig.FGJS_One_ZB;
            result.FGJS_Two_ZB = wConfig.FGJS_Two_ZB;
            result.FGJS_Three_ZB = wConfig.FGJS_Three_ZB;
            result.FGJS_Four_ZB = wConfig.FGJS_Four_ZB;

            if (wConfig.RepairFlag == 1) {
                result.FGJS_One = wConfig.FGJS_One;
                result.FGJS_Two = wConfig.FGJS_Two;
                result.FGJS_Three = wConfig.FGJS_Three;
                result.FGJS_Four = wConfig.FGJS_Four;

                return;
            }

            int wYear = Calendar.getInstance().get(Calendar.YEAR);
            int wMonth = Calendar.getInstance().get(Calendar.MONTH);

            Calendar wStartMonth = Calendar.getInstance();
            wStartMonth.set(wYear, wMonth, 1, 0, 0, 0);

            Calendar wEndMonth = Calendar.getInstance();
            wEndMonth.set(wYear, wMonth + 1, 1, 0, 0, 0);

            int wAreaID = 45;
            int wNumber = AndonDAO.getInstance().Andon_AsignRepairs(wLoginUser, wStartMonth, wEndMonth, wAreaID,
                    wErrorCode);
            result.FGJS_One = wNumber;

            wAreaID = 46;
            wNumber = AndonDAO.getInstance().Andon_AsignRepairs(wLoginUser, wStartMonth, wEndMonth, wAreaID,
                    wErrorCode);
            result.FGJS_Two = wNumber;

            wAreaID = 47;
            wNumber = AndonDAO.getInstance().Andon_AsignRepairs(wLoginUser, wStartMonth, wEndMonth, wAreaID,
                    wErrorCode);
            result.FGJS_Three = wNumber;

            wAreaID = 48;
            wNumber = AndonDAO.getInstance().Andon_AsignRepairs(wLoginUser, wStartMonth, wEndMonth, wAreaID,
                    wErrorCode);
            result.FGJS_Four = wNumber;
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 赋值全年统计数据
     */
    private void AsignStatisticalData(BMSEmployee wLoginUser, AndonConfig wConfig,
                                      AndonLocomotiveProductionStatus result) {
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            result.JHJF_Month = wConfig.JHJF_Month;
            result.JHJF_Month_C5 = wConfig.JHJF_Month_C5;
            result.JHJF_Month_C6 = wConfig.JHJF_Month_C6;

            if (wConfig.PlanFlag == 1) {
                result.LJXJ_Year = wConfig.LJXJ_Year;
                result.LJXJ_Year_C5 = wConfig.LJXJ_Year_C5;
                result.LJXJ_Year_C6 = wConfig.LJXJ_Year_C6;
                result.SJJF_Month = wConfig.SJJF_Month;
                result.SJJF_Month_C5 = wConfig.SJJF_Month_C5;
                result.SJJF_Month_C6 = wConfig.SJJF_Month_C6;

                return;
            }

            int wYear = Calendar.getInstance().get(Calendar.YEAR);
            int wMonth = Calendar.getInstance().get(Calendar.MONTH);

            Calendar wStartYear = Calendar.getInstance();
            wStartYear.set(wYear, 0, 1, 0, 0, 0);

            Calendar wEndYear = Calendar.getInstance();
            wEndYear.set(wYear, 11, 31, 23, 59, 59);

            Calendar wStartMonth = Calendar.getInstance();
            wStartMonth.set(wYear, wMonth, 1, 0, 0, 0);

            Calendar wEndMonth = Calendar.getInstance();
            wEndMonth.set(wYear, wMonth + 1, 1, 0, 0, 0);

            AndonLocomotiveProductionStatus wItem = AndonDAO.getInstance().AsignStatisticalData(wLoginUser, wStartYear,
                    wEndYear, wStartMonth, wEndMonth, wErrorCode);

            result.LJXJ_Year = wItem.LJXJ_Year;
            result.LJXJ_Year_C5 = wItem.LJXJ_Year_C5;
            result.LJXJ_Year_C6 = wItem.LJXJ_Year_C6;
            result.SJJF_Month = wItem.SJJF_Month;
            result.SJJF_Month_C5 = wItem.SJJF_Month_C5;
            result.SJJF_Month_C6 = wItem.SJJF_Month_C6;
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 赋值视频地址和播放类型
     */
    private void AsignUri(AndonConfig wConfig, AndonLocomotiveProductionStatus result) {
        try {
            result.Uri = wConfig.Uri;
            result.Type = wConfig.Type;
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 赋值工区生产进度
     */
    private void AsignAreaProgress(BMSEmployee wLoginUser, AndonConfig wConfig,
                                   AndonLocomotiveProductionStatus result) {
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            if (wConfig.ProgressFlag == 1) {
                result.Done_One = wConfig.Done_One;
                result.NotDone_One = wConfig.NotDone_One;
                result.Done_Two = wConfig.Done_Two;
                result.NotDone_Two = wConfig.NotDone_Two;
                result.Done_Three = wConfig.Done_Three;
                result.NotDone_Three = wConfig.NotDone_Three;
                result.Done_Four = wConfig.Done_Four;
                result.NotDone_Four = wConfig.NotDone_Four;

                return;
            }

            AndonLocomotiveProductionStatus wItem = AndonDAO.getInstance().Andon_AsignAreaProgress_V1(wLoginUser,
                    wErrorCode);
            result.Done_One = wItem.Done_One;
            result.NotDone_One = wItem.NotDone_One;
            result.Done_Two = wItem.Done_Two;
            result.NotDone_Two = wItem.NotDone_Two;
            result.Done_Three = wItem.Done_Three;
            result.NotDone_Three = wItem.NotDone_Three;
            result.Done_Four = wItem.Done_Four;
            result.NotDone_Four = wItem.NotDone_Four;
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 赋值不合格单，异常情况
     */
    private void AsingNcrAndExc(BMSEmployee wLoginUser, AndonConfig wConfig, AndonLocomotiveProductionStatus result) {
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            if (wConfig.NcrExcFlag == 1) {
                result.Total_Ncr = wConfig.Total_Ncr;
                result.Doing_Ncr = wConfig.Doing_Ncr;
                result.Total_Exc = wConfig.Total_Exc;
                result.Doing_Exc = wConfig.Doing_Exc;

                return;
            }

            int wYear = Calendar.getInstance().get(Calendar.YEAR);
            int wMonth = Calendar.getInstance().get(Calendar.MONTH);

            Calendar wStartMonth = Calendar.getInstance();
            wStartMonth.set(wYear, wMonth, 1, 0, 0, 0);

            Calendar wEndMonth = Calendar.getInstance();
            wEndMonth.set(wYear, wMonth + 1, 1, 0, 0, 0);

            AndonLocomotiveProductionStatus wItem = AndonDAO.getInstance().Andon_AsingNcrAndExc(wLoginUser, wStartMonth,
                    wEndMonth, wErrorCode);
            result.Total_Ncr = wItem.Total_Ncr;
            result.Doing_Ncr = wItem.Doing_Ncr;
            result.Total_Exc = wItem.Total_Exc;
            result.Doing_Exc = wItem.Doing_Exc;
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 赋值停时
     */
    private void AsignStopTimes(BMSEmployee wLoginUser, AndonConfig wConfig, AndonLocomotiveProductionStatus result) {
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            result.YHTS_C6_ZB = wConfig.YHTS_C6_ZB;
            result.YHTS_C5_ZB = wConfig.YHTS_C5_ZB;
            result.JCTS_C6_ZB = wConfig.JCTS_C6_ZB;
            result.JCTS_C5_ZB = wConfig.JCTS_C5_ZB;

            if (wConfig.StopFlag == 1) {
                result.YHTS_C6 = wConfig.YHTS_C6;
                result.YHTS_C5 = wConfig.YHTS_C5;
                result.JCTS_C6 = wConfig.JCTS_C6;
                result.JCTS_C5 = wConfig.JCTS_C5;

                return;
            }

            int wYear = Calendar.getInstance().get(Calendar.YEAR);

            Calendar wStartYear = Calendar.getInstance();
            wStartYear.set(wYear, 0, 1, 0, 0, 0);

            Calendar wEndYear = Calendar.getInstance();
            wEndYear.set(wYear, 11, 31, 23, 59, 59);

            AndonLocomotiveProductionStatus wItem = AndonDAO.getInstance().Andon_AsignStopTimes(wLoginUser, wStartYear,
                    wEndYear, wErrorCode);
            result.YHTS_C6 = wItem.YHTS_C6;
            result.YHTS_C5 = wItem.YHTS_C5;
            result.JCTS_C6 = wItem.JCTS_C6;
            result.JCTS_C5 = wItem.JCTS_C5;
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    @Override
    public ServiceResult<List<AndonDayPlanPartCashingRate>> Andon_QueryPartDayPlanRate(BMSEmployee wLoginUser,
                                                                                       Calendar wSTime,
                                                                                       Calendar wETime,
                                                                                       String wPartIDs,
                                                                                       String wOrderIDs) {
        ServiceResult<List<AndonDayPlanPartCashingRate>> wResult =
                new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<Integer> wOrderIDList = new ArrayList<>();
            if (StringUtils.isNotEmpty(wOrderIDs) && !wOrderIDs.equals("-1")) {
                String[] wStrs = wOrderIDs.split(",");
                for (String wStr : wStrs) {
                    wOrderIDList.add(StringUtils.parseInt(wStr));
                }
            }
            List<Integer> wPartIDParamList = new ArrayList<>();
            if (StringUtils.isNotEmpty(wPartIDs) && !wPartIDs.equals("-1")) {
                String[] wStrs = wPartIDs.split(",");
                for (String wStr : wStrs) {
                    wPartIDParamList.add(StringUtils.parseInt(wStr));
                }
            }

            // ①查询已排好序的工位id集合
            List<Integer> wSortedPartIDList = AndonDAO.getInstance().Andon_QuerySortedPartIDList(wLoginUser,
                    wErrorCode);
            // ①获取工位集合
            List<Integer> wPartIDList = AndonDAO.getInstance().Andon_QueryPartDayPlanIDList(wLoginUser, wErrorCode);
            // ②遍历工位，获取日计划数
            for (int wPartID : wSortedPartIDList) {
                if (wPartIDList.stream().noneMatch(p -> p == wPartID)) {
                    continue;
                }
                AndonDayPlanPartCashingRate wRate = AndonDAO.getInstance().Andon_QueryPartDayPlan(wLoginUser, wPartID,
                        wOrderIDList, wSTime, wETime, wErrorCode);
                if (wRate.TotalNumber > 0) {
                    wResult.Result.add(wRate);
                }
            }

            if (wPartIDParamList.size() > 0) {
                wResult.Result = wResult.Result.stream()
                        .filter(p -> wPartIDParamList.stream().anyMatch(q -> q == p.PartID))
                        .collect(Collectors.toList());
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<AndonDayPlanClassCashingRate>> Andon_QueryClassDayPlanRate(BMSEmployee wLoginUser,
                                                                                         Calendar wSTime,
                                                                                         Calendar wETime,
                                                                                         String wClassIDs,
                                                                                         String wOrderIDs) {
        ServiceResult<List<AndonDayPlanClassCashingRate>> wResult =
                new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<Integer> wOrderIDList = new ArrayList<>();
            if (StringUtils.isNotEmpty(wOrderIDs) && !wOrderIDs.equals("-1")) {
                String[] wStrs = wOrderIDs.split(",");
                for (String wStr : wStrs) {
                    wOrderIDList.add(StringUtils.parseInt(wStr));
                }
            }
            List<Integer> wClassIDParamList = new ArrayList<>();
            if (StringUtils.isNotEmpty(wClassIDs) && !wClassIDs.equals("-1")) {
                String[] wStrs = wClassIDs.split(",");
                for (String wStr : wStrs) {
                    wClassIDParamList.add(StringUtils.parseInt(wStr));
                }
            }

            // ①获取激活的班组工位列表
            List<BMSWorkCharge> wList = CoreServiceImpl.getInstance().FMC_QueryWorkChargeList(wLoginUser)
                    .List(BMSWorkCharge.class);
            if (wList == null || wList.size() <= 0) {
                return wResult;
            }
            wList = wList.stream().filter(p -> p.Active == 1).collect(Collectors.toList());
            // ②提取班组
            List<Integer> wClassIDList = wList.stream().map(p -> p.ClassID).distinct().collect(Collectors.toList());
            // ③遍历获取工位列表，根据工位日计划兑现率
            for (int wClassID : wClassIDList) {
                List<BMSWorkCharge> wPartChargeList = wList.stream().filter(p -> p.ClassID == wClassID)
                        .collect(Collectors.toList());

                int wFSize = 0;
                int wTSize = 0;

                for (BMSWorkCharge wItem : wPartChargeList) {
                    AndonDayPlanPartCashingRate wRate = AndonDAO.getInstance().Andon_QueryPartDayPlan(wLoginUser,
                            wItem.StationID, wOrderIDList, wSTime, wETime, wErrorCode);
                    wFSize += wRate.FinishNumber;
                    wTSize += wRate.TotalNumber;
                }

                double wAv = 0.0;
                if (wTSize > 0) {
                    wAv = new BigDecimal((double) wFSize / wTSize).setScale(2, RoundingMode.HALF_UP).doubleValue();
                }

                String wClassName = APSConstans.GetBMSDepartmentName(wClassID);

                if (wTSize <= 0) {
                    continue;
                }
                AndonDayPlanClassCashingRate wRateNew = new AndonDayPlanClassCashingRate(wClassID, wClassName, wFSize,
                        wTSize, wAv * 100);
                wResult.Result.add(wRateNew);
            }

            // 筛选工区
            if (wClassIDParamList.size() > 0) {
                wResult.Result = wResult.Result.stream()
                        .filter(p -> wClassIDParamList.stream().anyMatch(q -> q == p.ClassID))
                        .collect(Collectors.toList());
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<AndonDayPlanAreaCashingRate>> Andon_QueryAreaDayPlanRate(BMSEmployee wLoginUser,
                                                                                       Calendar wSTime,
                                                                                       Calendar wETime,
                                                                                       String wAreaIDs,
                                                                                       String wOrderIDs) {
        ServiceResult<List<AndonDayPlanAreaCashingRate>> wResult =
                new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<Integer> wOrderIDList = new ArrayList<>();
            if (StringUtils.isNotEmpty(wOrderIDs) && !wOrderIDs.equals("-1")) {
                String[] wStrs = wOrderIDs.split(",");
                for (String wStr : wStrs) {
                    wOrderIDList.add(StringUtils.parseInt(wStr));
                }
            }
            List<Integer> wAreaIDParamList = new ArrayList<>();
            if (StringUtils.isNotEmpty(wAreaIDs) && !wAreaIDs.equals("-1")) {
                String[] wStrs = wAreaIDs.split(",");
                for (String wStr : wStrs) {
                    wAreaIDParamList.add(StringUtils.parseInt(wStr));
                }
            }

            // ①获取激活的班组工位列表
            List<LFSWorkAreaStation> wList = APSConstans.GetLFSWorkAreaStationList().values().stream()
                    .filter(p -> p.Active == 1 && p.WorkAreaID > 0).collect(Collectors.toList());
            if (wList.size() <= 0) {
                return wResult;
            }
            // ②提取工区
            List<Integer> wAreaIDList =
                    wList.stream().map(p -> p.WorkAreaID).distinct().sorted().collect(Collectors.toList());

            // ③遍历获取工位列表，根据工位日计划兑现率
            for (int wAreaID : wAreaIDList) {
                List<LFSWorkAreaStation> wWSList = wList.stream().filter(p -> p.WorkAreaID == wAreaID)
                        .collect(Collectors.toList());

                int wFSize = 0;
                int wTSize = 0;

                for (LFSWorkAreaStation wItem : wWSList) {
                    AndonDayPlanPartCashingRate wRate = AndonDAO.getInstance().Andon_QueryPartDayPlan(wLoginUser,
                            wItem.StationID, wOrderIDList, wSTime, wETime, wErrorCode);
                    wFSize += wRate.FinishNumber;
                    wTSize += wRate.TotalNumber;
                }

                double wAv = 0.0;
                if (wTSize > 0) {
                    wAv = new BigDecimal((double) wFSize / wTSize).setScale(2, RoundingMode.HALF_UP).doubleValue();
                }

                String wClassName = APSConstans.GetBMSDepartmentName(wAreaID);

                AndonDayPlanAreaCashingRate wRateNew = new AndonDayPlanAreaCashingRate(wAreaID, wClassName, wFSize,
                        wTSize, wAv * 100);
                wResult.Result.add(wRateNew);
            }

            // 筛选工区
            if (wAreaIDParamList.size() > 0) {
                wResult.Result = wResult.Result.stream()
                        .filter(p -> wAreaIDParamList.stream().anyMatch(q -> q == p.AreaID))
                        .collect(Collectors.toList());
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<AndonDayPlanAreaCashingRate>> Andon_QueryAreaMonthPlanRate(BMSEmployee wLoginUser,
                                                                                         Calendar wSDate,
                                                                                         Calendar wEDate,
                                                                                         String wAreaIDs,
                                                                                         String wOrderIDs) {
        ServiceResult<List<AndonDayPlanAreaCashingRate>> wResult =
                new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wSDate.compareTo(wEDate) > 0) {
                return wResult;
            }

            wSDate.set(wSDate.get(Calendar.YEAR), wSDate.get(Calendar.MONTH), wSDate.get(Calendar.DATE), 0, 0, 0);

            wEDate.set(wSDate.get(Calendar.YEAR), wSDate.get(Calendar.MONTH), wSDate.get(Calendar.DATE), 23, 59, 59);

            List<AndonDayPlanAreaCashingRate> wList = Andon_QueryAreaDayPlanRate(wLoginUser, wSDate, wEDate, wAreaIDs,
                    wOrderIDs).Result;
            List<AndonDayPlanAreaCashingRate> wAllList = new ArrayList<>(wList);

            // ①提取工区
            List<Integer> wAreaIDList = wAllList.stream().map(p -> p.AreaID).distinct().collect(Collectors.toList());
            // ②遍历求平均数
            for (int wAreaID : wAreaIDList) {
                List<AndonDayPlanAreaCashingRate> wTempList = wAllList.stream()
                        .filter(p -> p.TotalNumber > 0 && p.AreaID == wAreaID).collect(Collectors.toList());
                if (wTempList.size() > 0) {

                    double wT = 0;
                    for (AndonDayPlanAreaCashingRate wAndonDayPlanAreaCashingRate : wTempList) {
                        wT += wAndonDayPlanAreaCashingRate.Rate;
                    }
                    double wAv = new BigDecimal(wT / wTempList.size()).setScale(1, RoundingMode.HALF_UP)
                            .doubleValue();

                    AndonDayPlanAreaCashingRate wRate = new AndonDayPlanAreaCashingRate(wAreaID,
                            wTempList.get(0).AreaName, 0, 0, wAv);
                    wResult.Result.add(wRate);
                } else {
                    String wName = wAllList.stream().filter(p -> p.AreaID == wAreaID).findFirst().get().AreaName;
                    AndonDayPlanAreaCashingRate wRate = new AndonDayPlanAreaCashingRate(wAreaID, wName, 0, 0, 0);
                    wResult.Result.add(wRate);
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<AndonDayPlanClassCashingRate>> Andon_QueryClassMonthPlanRate(BMSEmployee wLoginUser,
                                                                                           Calendar wSDate,
                                                                                           Calendar wEDate,
                                                                                           String wClassIDs,
                                                                                           String wOrderIDs) {
        ServiceResult<List<AndonDayPlanClassCashingRate>> wResult =
                new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wSDate.compareTo(wEDate) > 0) {
                return wResult;
            }

            wSDate.set(wSDate.get(Calendar.YEAR), wSDate.get(Calendar.MONTH), wSDate.get(Calendar.DATE), 0, 0, 0);

            wEDate.set(wSDate.get(Calendar.YEAR), wSDate.get(Calendar.MONTH), wSDate.get(Calendar.DATE), 23, 59, 59);

            List<AndonDayPlanClassCashingRate> wList = Andon_QueryClassDayPlanRate(wLoginUser, wSDate, wEDate,
                    wClassIDs, wOrderIDs).Result;
            List<AndonDayPlanClassCashingRate> wAllList = new ArrayList<>(wList);

            // ①提取班组
            List<Integer> wClassIDList = wAllList.stream().map(p -> p.ClassID).distinct().collect(Collectors.toList());
            // ②遍历求平均数
            for (int wClassID : wClassIDList) {
                List<AndonDayPlanClassCashingRate> wTempList = wAllList.stream()
                        .filter(p -> p.TotalNumber > 0 && p.ClassID == wClassID).collect(Collectors.toList());
                if (wTempList.size() > 0) {

                    double wT = 0;
                    for (AndonDayPlanClassCashingRate wAndonDayPlanAreaCashingRate : wTempList) {
                        wT += wAndonDayPlanAreaCashingRate.Rate;
                    }
                    double wAv = BigDecimal.valueOf(wT / wTempList.size()).setScale(1, RoundingMode.HALF_UP)
                            .doubleValue();

                    AndonDayPlanClassCashingRate wRate = new AndonDayPlanClassCashingRate(wClassID,
                            wTempList.get(0).ClassName, 0, 0, wAv);
                    wResult.Result.add(wRate);
                } else {
                    String wName = wAllList.stream().filter(p -> p.ClassID == wClassID).findFirst().get().ClassName;
                    AndonDayPlanClassCashingRate wRate = new AndonDayPlanClassCashingRate(wClassID, wName, 0, 0, 0);
                    wResult.Result.add(wRate);
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<AndonDayPlanPartCashingRate>> Andon_QueryPartMonthPlanRate(BMSEmployee wLoginUser,
                                                                                         Calendar wSDate,
                                                                                         Calendar wEDate,
                                                                                         String wPartIDs,
                                                                                         String wOrderIDs) {
        ServiceResult<List<AndonDayPlanPartCashingRate>> wResult =
                new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wSDate.compareTo(wEDate) > 0) {
                return wResult;
            }

            wSDate.set(wSDate.get(Calendar.YEAR), wSDate.get(Calendar.MONTH), wSDate.get(Calendar.DATE), 0, 0, 0);

            wEDate.set(wSDate.get(Calendar.YEAR), wSDate.get(Calendar.MONTH), wSDate.get(Calendar.DATE), 23, 59, 59);

            List<AndonDayPlanPartCashingRate> wList = Andon_QueryPartDayPlanRate(wLoginUser, wSDate, wEDate, wPartIDs,
                    wOrderIDs).Result;
            List<AndonDayPlanPartCashingRate> wAllList = new ArrayList<>(wList);

            // ①提取工位
            List<Integer> wPartIDList = wAllList.stream().map(p -> p.PartID).distinct().collect(Collectors.toList());
            // ②遍历求平均数
            for (int wPartID : wPartIDList) {
                List<AndonDayPlanPartCashingRate> wTempList = wAllList.stream()
                        .filter(p -> p.TotalNumber > 0 && p.PartID == wPartID).collect(Collectors.toList());
                if (wTempList.size() > 0) {

                    double wT = 0;
                    for (AndonDayPlanPartCashingRate wAndonDayPlanAreaCashingRate : wTempList) {
                        wT += wAndonDayPlanAreaCashingRate.Rate;
                    }
                    double wAv = new BigDecimal(wT / wTempList.size()).setScale(1, RoundingMode.HALF_UP)
                            .doubleValue();

                    AndonDayPlanPartCashingRate wRate = new AndonDayPlanPartCashingRate(wPartID,
                            wTempList.get(0).PartName, 0, 0, wAv);
                    wResult.Result.add(wRate);
                } else {
                    String wName = wAllList.stream().filter(p -> p.PartID == wPartID).findFirst().get().PartName;
                    AndonDayPlanPartCashingRate wRate = new AndonDayPlanPartCashingRate(wPartID, wName, 0, 0, 0);
                    wResult.Result.add(wRate);
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> Andon_ExportTrainStatus(BMSEmployee wLoginUser) {
        ServiceResult<String> wResult = new ServiceResult<>();
        wResult.Result = "";
        try {
            AndonScreen wScreen = AndonServiceImpl.getInstance().Andon_QueryAndonScreen(wLoginUser).Result;
            // 检修概况
            MyExcelSheet wMyExcelSheet = GetMyExcelSheet(wScreen);
            // 在厂台车列表
            MyExcelSheet wMyExcelSheet1 = GetwMyExcelSheet1(wScreen);

            List<MyExcelSheet> wMyExcelSheetList = new ArrayList<>(
                    Arrays.asList(wMyExcelSheet, wMyExcelSheet1));

            wResult.Result = ExcelUtil.ExportData(wMyExcelSheetList, "广州电力机车MES系统生产状态监控");
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 获取在厂台车状态列表
     */
    private MyExcelSheet GetwMyExcelSheet1(AndonScreen wScreen) {
        MyExcelSheet wResult = new MyExcelSheet();
        try {
            wResult.SheetName = "在厂台车列表";
            wResult.HeaderList = new ArrayList<>(Arrays.asList("车号", "配属局段", "修程", "进厂日期", "停时", "库位", "台位", "工位",
                    "计划完工日期", "提前/落后(天)", "完成数", "剩余数", "完成进度", "返修", "不合格评审", "异常", "状态"));
            wResult.TitleName = "在厂台车列表";
            wResult.DataList = new ArrayList<>();

            SimpleDateFormat wSDF = new SimpleDateFormat("yyyy-MM-dd");

            for (OrderTimeInfo wOrderTimeInfo : wScreen.TrainItemList) {
                List<String> wList = new ArrayList<>();

                wList.add(wOrderTimeInfo.PartNo);
                wList.add(wOrderTimeInfo.CustomerName);
                wList.add(wOrderTimeInfo.LineName);
                wList.add(wSDF.format(wOrderTimeInfo.InPlantTime.getTime()));
                wList.add(String.valueOf(wOrderTimeInfo.StopTime));
                wList.add(wOrderTimeInfo.StockName);
                wList.add(wOrderTimeInfo.PlaceName);
                wList.add(wOrderTimeInfo.StationName + "(" + wSDF.format(wOrderTimeInfo.PlanStartTime.getTime()) + ")");
                wList.add(wSDF.format(wOrderTimeInfo.PlanEndTime.getTime()));
                wList.add(String.valueOf(wOrderTimeInfo.PlanSituation));
                wList.add(String.valueOf(wOrderTimeInfo.FinishNum));
                wList.add(String.valueOf(wOrderTimeInfo.SurplusNum));
                if (wOrderTimeInfo.SurplusNum + wOrderTimeInfo.FinishNum <= 0) {
                    wList.add("0%");
                } else {
                    double wRate =
                            BigDecimal.valueOf((double) wOrderTimeInfo.FinishNum / (wOrderTimeInfo.FinishNum + wOrderTimeInfo.SurplusNum))
                                    .setScale(2, RoundingMode.HALF_UP).doubleValue();
                    wList.add((int) (wRate * 100) + "%");
                }
                wList.add(String.valueOf(wOrderTimeInfo.ReworkNum));
                wList.add(String.valueOf(wOrderTimeInfo.NcrNum));
                wList.add(String.valueOf(wOrderTimeInfo.ExcNum));
                wList.add(wOrderTimeInfo.Status);

                wResult.DataList.add(wList);

            }

        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 获取检修概况Excel数据
     */
    private MyExcelSheet GetMyExcelSheet(AndonScreen wScreen) {
        MyExcelSheet wResult = new MyExcelSheet();
        try {
            wResult.SheetName = "检修概况";
            wResult.HeaderList = new ArrayList<>(Arrays.asList("全年累计修竣", "C5修累计修竣", "C6修累计修竣", "本月竣工数", "在厂机车",
                    "在修机车", "待完工任务", "今日新增异常", "不合格评审数", "返修数"));
            wResult.TitleName = "检修概况";
            wResult.DataList = new ArrayList<>();
            List<String> wList = new ArrayList<>(Arrays.asList(String.valueOf(wScreen.YearReport.AnnualNum),
                    String.valueOf(wScreen.YearReport.AnnualC5Num), String.valueOf(wScreen.YearReport.AnnualC6Num),
                    String.valueOf(wScreen.YearReport.ThisMonthNum), String.valueOf(wScreen.YearReport.LocoCar),
                    String.valueOf(wScreen.YearReport.RepairCar), String.valueOf(wScreen.YearReport.stationTask),
                    String.valueOf(wScreen.YearReport.ExcTask), String.valueOf(wScreen.YearReport.ncrTask),
                    String.valueOf(wScreen.YearReport.repairTask)));
            wResult.DataList.add(wList);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> Andon_ExportAreaRate(BMSEmployee wLoginUser, List<AndonDayPlanAreaCashingRate> wList) {
        ServiceResult<String> wResult = new ServiceResult<>();
        wResult.Result = "";
        try {
            MyExcelSheet wMyExcelSheet = GetAreaRateExcelSheet(wList);

            List<MyExcelSheet> wMyExcelSheetList = new ArrayList<>(Collections.singletonList(wMyExcelSheet));

            wResult.Result = ExcelUtil.ExportData(wMyExcelSheetList, "工区兑现率");
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 获取工区兑现率sheet
     */
    private MyExcelSheet GetAreaRateExcelSheet(List<AndonDayPlanAreaCashingRate> wList) {
        MyExcelSheet wResult = new MyExcelSheet();
        try {
            wResult.SheetName = "工区兑现率";
            wResult.TitleName = "工区兑现率";
            wResult.HeaderList = wList.stream().map(p -> p.AreaName).distinct().collect(Collectors.toList());
            wResult.DataList = new ArrayList<>();
            List<String> wValueList = new ArrayList<>();
            for (AndonDayPlanAreaCashingRate wAndonDayPlanAreaCashingRate : wList) {
                wValueList.add(wAndonDayPlanAreaCashingRate.Rate * 100 + "%");
            }
            wResult.DataList.add(wValueList);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> Andon_ExportClassRate(BMSEmployee wLoginUser,
                                                       List<AndonDayPlanClassCashingRate> wList) {
        ServiceResult<String> wResult = new ServiceResult<>();
        wResult.Result = "";
        try {
            MyExcelSheet wMyExcelSheet = GetClassRateExcelSheet(wList);

            List<MyExcelSheet> wMyExcelSheetList = new ArrayList<>(Collections.singletonList(wMyExcelSheet));

            wResult.Result = ExcelUtil.ExportData(wMyExcelSheetList, "班组兑现率");
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    private MyExcelSheet GetClassRateExcelSheet(List<AndonDayPlanClassCashingRate> wList) {
        MyExcelSheet wResult = new MyExcelSheet();
        try {
            wResult.SheetName = "班组兑现率";
            wResult.TitleName = "班组兑现率";
            wResult.HeaderList = wList.stream().map(p -> p.ClassName).distinct().collect(Collectors.toList());
            wResult.DataList = new ArrayList<>();
            List<String> wValueList = new ArrayList<>();
            for (AndonDayPlanClassCashingRate wAndonDayPlanAreaCashingRate : wList) {
                wValueList.add(wAndonDayPlanAreaCashingRate.Rate * 100 + "%");
            }
            wResult.DataList.add(wValueList);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> Andon_ExportPartRate(BMSEmployee wLoginUser, List<AndonDayPlanPartCashingRate> wList) {
        ServiceResult<String> wResult = new ServiceResult<>();
        wResult.Result = "";
        try {
            MyExcelSheet wMyExcelSheet = GetPartRateExcelSheet(wList);

            List<MyExcelSheet> wMyExcelSheetList = new ArrayList<>(Collections.singletonList(wMyExcelSheet));

            wResult.Result = ExcelUtil.ExportData(wMyExcelSheetList, "工位兑现率");
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    private MyExcelSheet GetPartRateExcelSheet(List<AndonDayPlanPartCashingRate> wList) {
        MyExcelSheet wResult = new MyExcelSheet();
        try {
            wResult.SheetName = "工位兑现率";
            wResult.TitleName = "工位兑现率";
            wResult.HeaderList = wList.stream().map(p -> p.PartName).distinct().collect(Collectors.toList());
            wResult.DataList = new ArrayList<>();
            List<String> wValueList = new ArrayList<>();
            for (AndonDayPlanPartCashingRate wAndonDayPlanAreaCashingRate : wList) {
                wValueList.add(wAndonDayPlanAreaCashingRate.Rate * 100 + "%");
            }
            wResult.DataList.add(wValueList);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<FPCPart>> APS_QueryPartList(BMSEmployee wLoginUser, String wAreaID, String wClassID) {
        ServiceResult<List<FPCPart>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // ①工区筛选工位
            List<Integer> wAreaPartIDList = null;
            if (StringUtils.isNotEmpty(wAreaID) && !wAreaID.equals("-1")) {
                List<Integer> wAreaIDList = new ArrayList<>();
                String[] wStrs = wAreaID.split(",");
                for (String wStr : wStrs) {
                    wAreaIDList.add(StringUtils.parseInt(wStr));
                }

                wAreaPartIDList = AndonDAO.getInstance().Andon_QueryAreaPartIDList(wLoginUser, wAreaIDList, wErrorCode);
            }

            // ②班组筛选工位
            List<Integer> wClassPartIDList = null;
            if (StringUtils.isNotEmpty(wClassID) && !wClassID.equals("-1")) {
                List<Integer> wClassIDList = new ArrayList<>();
                String[] wStrs = wClassID.split(",");
                for (String wStr : wStrs) {
                    wClassIDList.add(StringUtils.parseInt(wStr));
                }

                wClassPartIDList = AndonDAO.getInstance().Andon_QueryClassPartIDList(wLoginUser, wClassIDList,
                        wErrorCode);
            }

            // ③取交集
            if (wAreaPartIDList != null && wClassPartIDList != null) {
                List<Integer> wCloneList = wClassPartIDList;
                wAreaPartIDList = wAreaPartIDList.stream().filter(p -> wCloneList.stream().anyMatch(q -> q.equals(p)))
                        .collect(Collectors.toList());
                for (int wPartID : wAreaPartIDList) {
                    FPCPart wPart = APSConstans.GetFPCPart(wPartID);
                    if (wPart.ID > 0) {
                        wResult.Result.add(wPart);
                    }
                }
            } else {
                if (wAreaPartIDList != null && wAreaPartIDList.size() > 0) {
                    for (int wPartID : wAreaPartIDList) {
                        FPCPart wPart = APSConstans.GetFPCPart(wPartID);
                        if (wPart.ID > 0) {
                            wResult.Result.add(wPart);
                        }
                    }
                } else {
                    assert wClassPartIDList != null;
                    for (int wPartID : wClassPartIDList) {
                        FPCPart wPart = APSConstans.GetFPCPart(wPartID);
                        if (wPart.ID > 0) {
                            wResult.Result.add(wPart);
                        }
                    }
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> Andon_ProductionDaily2(BMSEmployee wLoginUser, int wYear) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // ①解析年度时间
            Calendar wSTime = Calendar.getInstance();
            wSTime.set(wYear, 0, 1, 0, 0, 0);
            Calendar wETime = Calendar.getInstance();
            wETime.set(wYear, 11, 31, 23, 59, 59);
            // ②根据时间查询实际到厂时间在当年的订单ID集合
            List<Integer> wIDList = OMSOrderDAO.getInstance().SelectListByYearTime(wLoginUser, wSTime, wETime,
                    wErrorCode);
            // ③根据订单ID集合获取订单列表
            List<OMSOrder> wOrderList = OMSOrderDAO.getInstance().SelectListByIDList(wLoginUser, wIDList, wErrorCode);
            wOrderList.removeIf(p -> p.PartNo.contains("XS") || p.PartNo.contains("GL"));
            // 移除广铁的订单
            wOrderList.removeIf(p -> p.CustomerID == 43);
            // ④C5统计
            List<OMSOrder> wC5List = wOrderList.stream().filter(p -> p.LineID == 1).collect(Collectors.toList());

            int wMonth = Calendar.getInstance().get(Calendar.MONTH);

            Calendar wMSTime = Calendar.getInstance();
            wMSTime.set(wYear, wMonth, 1, 0, 0, 0);

            Calendar wMETime = Calendar.getInstance();
            wMETime.set(wYear, wMonth + 1, 1, 0, 0, 0);

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2010, 0, 1, 0, 0, 0);

            int bYJG = (int) wC5List.stream()
                    .filter(p -> p.RealFinishDate.compareTo(wMSTime) >= 0 && p.RealFinishDate.compareTo(wMETime) <= 0)
                    .count();
            int lJJG = (int) wC5List.stream().filter(p -> p.RealFinishDate.compareTo(wBaseTime) >= 0).count();
            double dBJXTS = 0;
            double sJJXTS = 0;
            double zCTS = 0;
            double zTTS = 0;
            double yHTS = 0;
            for (OMSOrder omsOrder : wC5List) {
                dBJXTS += omsOrder.TelegraphRepairStopTimes;
                sJJXTS += omsOrder.ActualRepairStopTimes;
                zCTS += omsOrder.InPlantStopTimes;
                zTTS += omsOrder.OnTheWayStopTimes;
                yHTS += omsOrder.PosterioriStopTimes;
            }

            if (dBJXTS > 0) {
                dBJXTS = new BigDecimal(dBJXTS / wC5List.size()).setScale(1, RoundingMode.HALF_UP)
                        .doubleValue();
            }
            if (sJJXTS > 0) {
                sJJXTS = new BigDecimal(sJJXTS / wC5List.size()).setScale(1, RoundingMode.HALF_UP)
                        .doubleValue();
            }
            if (zCTS > 0) {
                zCTS = new BigDecimal(zCTS / wC5List.size()).setScale(1, RoundingMode.HALF_UP)
                        .doubleValue();
            }
            if (zTTS > 0) {
                zTTS = new BigDecimal(zTTS / wC5List.size()).setScale(1, RoundingMode.HALF_UP)
                        .doubleValue();
            }
            if (yHTS > 0) {
                yHTS = new BigDecimal(yHTS / wC5List.size()).setScale(1, RoundingMode.HALF_UP)
                        .doubleValue();
            }

            AndonStopStatistics wC5Total = new AndonStopStatistics(1, "C5", wC5List.size(), bYJG, lJJG, dBJXTS, sJJXTS,
                    zCTS, zTTS, yHTS);
            wResult.CustomResult.put("C5Total", wC5Total);
            // ⑤C5订单
            wResult.CustomResult.put("C5", wC5List);
            // ⑥C6统计
            List<OMSOrder> wC6List = wOrderList.stream().filter(p -> p.LineID == 2).collect(Collectors.toList());

            bYJG = (int) wC6List.stream()
                    .filter(p -> p.RealFinishDate.compareTo(wMSTime) >= 0 && p.RealFinishDate.compareTo(wMETime) <= 0)
                    .count();
            lJJG = (int) wC6List.stream().filter(p -> p.RealFinishDate.compareTo(wBaseTime) >= 0).count();
            dBJXTS = 0;
            sJJXTS = 0;
            zCTS = 0;
            zTTS = 0;
            yHTS = 0;
            for (OMSOrder omsOrder : wC6List) {
                dBJXTS += omsOrder.TelegraphRepairStopTimes;
                sJJXTS += omsOrder.ActualRepairStopTimes;
                zCTS += omsOrder.InPlantStopTimes;
                zTTS += omsOrder.OnTheWayStopTimes;
                yHTS += omsOrder.PosterioriStopTimes;
            }

            if (dBJXTS > 0) {
                dBJXTS = BigDecimal.valueOf(dBJXTS / wC6List.size()).setScale(1, RoundingMode.HALF_UP)
                        .doubleValue();
            }
            if (sJJXTS > 0) {
                sJJXTS = BigDecimal.valueOf(sJJXTS / wC6List.size()).setScale(1, RoundingMode.HALF_UP)
                        .doubleValue();
            }
            if (zCTS > 0) {
                zCTS = BigDecimal.valueOf(zCTS / wC6List.size()).setScale(1, RoundingMode.HALF_UP)
                        .doubleValue();
            }
            if (zTTS > 0) {
                zTTS = BigDecimal.valueOf(zTTS / wC6List.size()).setScale(1, RoundingMode.HALF_UP)
                        .doubleValue();
            }
            if (yHTS > 0) {
                yHTS = BigDecimal.valueOf(yHTS / wC6List.size()).setScale(1, RoundingMode.HALF_UP)
                        .doubleValue();
            }

            AndonStopStatistics wC6Total = new AndonStopStatistics(2, "C6", wC6List.size(), bYJG, lJJG, dBJXTS, sJJXTS,
                    zCTS, zTTS, yHTS);
            wResult.CustomResult.put("C6Total", wC6Total);
            // ⑦C6订单
            wResult.CustomResult.put("C6", wC6List);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> Andon_ProductionDaily3(BMSEmployee wLoginUser, int wYear) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // ①获取年度时间
            Calendar wSTime = Calendar.getInstance();
            wSTime.set(wYear, 0, 1, 0, 0, 0);
            Calendar wETime = Calendar.getInstance();
            wETime.set(wYear, 11, 31, 23, 59, 59);
            // ②根据时间和状态查询订单集合
            List<Integer> wStatusList = new ArrayList<>(Arrays.asList(5, 6, 7, 8));
            List<OMSOrder> wOrderList = OMSOrderDAO.getInstance().SelectList(wLoginUser, null, null, wSTime, wETime,
                    wStatusList, null, "", new ArrayList<>(Collections.singletonList(1)), wErrorCode);
            wOrderList.removeIf(p -> p.PartNo.contains("XS") || p.PartNo.contains("GL"));
            // ③筛选局段和机型
            List<OMSOrder> wList = wOrderList.stream().collect(Collectors.collectingAndThen(
                    Collectors.toCollection(() -> new TreeSet<>(Comparator
                            .comparing(o -> o.getLineID() + ";" + o.getBureauSectionID() + ";" + o.getProductID()))),
                    ArrayList::new));
            // ④统计数据
            List<AndonYearFinishSituation> wTList = new ArrayList<>();
            for (OMSOrder omsOrder : wList) {

                // ①1月
                Calendar wSMTime1 = Calendar.getInstance();
                wSMTime1.set(wYear, 0, 1, 0, 0, 0);
                Calendar wEMTime1 = Calendar.getInstance();
                wEMTime1.set(wYear, 1, 1, 0, 0, 0);
                int month1 = (int) wOrderList.stream()
                        .filter(p -> p.LineID == omsOrder.LineID && p.CustomerID == omsOrder.CustomerID
                                && p.ProductID == omsOrder.ProductID && p.RealFinishDate.compareTo(wSMTime1) >= 0
                                && p.RealFinishDate.compareTo(wEMTime1) < 0)
                        .count();
                // ②2月
                Calendar wSMTime2 = Calendar.getInstance();
                wSMTime2.set(wYear, 1, 1, 0, 0, 0);
                Calendar wEMTime2 = Calendar.getInstance();
                wEMTime2.set(wYear, 2, 1, 0, 0, 0);
                int month2 = (int) wOrderList.stream()
                        .filter(p -> p.LineID == omsOrder.LineID && p.CustomerID == omsOrder.CustomerID
                                && p.ProductID == omsOrder.ProductID && p.RealFinishDate.compareTo(wSMTime2) >= 0
                                && p.RealFinishDate.compareTo(wEMTime2) < 0)
                        .count();
                // ③3月
                Calendar wSMTime3 = Calendar.getInstance();
                wSMTime3.set(wYear, 2, 1, 0, 0, 0);
                Calendar wEMTime3 = Calendar.getInstance();
                wEMTime3.set(wYear, 3, 1, 0, 0, 0);
                int month3 = (int) wOrderList.stream()
                        .filter(p -> p.LineID == omsOrder.LineID && p.CustomerID == omsOrder.CustomerID
                                && p.ProductID == omsOrder.ProductID && p.RealFinishDate.compareTo(wSMTime3) >= 0
                                && p.RealFinishDate.compareTo(wEMTime3) < 0)
                        .count();
                // ④4月
                Calendar wSMTime4 = Calendar.getInstance();
                wSMTime4.set(wYear, 3, 1, 0, 0, 0);
                Calendar wEMTime4 = Calendar.getInstance();
                wEMTime4.set(wYear, 4, 1, 0, 0, 0);
                int month4 = (int) wOrderList.stream()
                        .filter(p -> p.LineID == omsOrder.LineID && p.CustomerID == omsOrder.CustomerID
                                && p.ProductID == omsOrder.ProductID && p.RealFinishDate.compareTo(wSMTime4) >= 0
                                && p.RealFinishDate.compareTo(wEMTime4) < 0)
                        .count();
                // ⑤5月
                Calendar wSMTime5 = Calendar.getInstance();
                wSMTime5.set(wYear, 4, 1, 0, 0, 0);
                Calendar wEMTime5 = Calendar.getInstance();
                wEMTime5.set(wYear, 5, 1, 0, 0, 0);
                int month5 = (int) wOrderList.stream()
                        .filter(p -> p.LineID == omsOrder.LineID && p.CustomerID == omsOrder.CustomerID
                                && p.ProductID == omsOrder.ProductID && p.RealFinishDate.compareTo(wSMTime5) >= 0
                                && p.RealFinishDate.compareTo(wEMTime5) < 0)
                        .count();
                // ⑥6月
                Calendar wSMTime6 = Calendar.getInstance();
                wSMTime6.set(wYear, 5, 1, 0, 0, 0);
                Calendar wEMTime6 = Calendar.getInstance();
                wEMTime6.set(wYear, 6, 1, 0, 0, 0);
                int month6 = (int) wOrderList.stream()
                        .filter(p -> p.LineID == omsOrder.LineID && p.CustomerID == omsOrder.CustomerID
                                && p.ProductID == omsOrder.ProductID && p.RealFinishDate.compareTo(wSMTime6) >= 0
                                && p.RealFinishDate.compareTo(wEMTime6) < 0)
                        .count();
                // ⑦7月
                Calendar wSMTime7 = Calendar.getInstance();
                wSMTime7.set(wYear, 6, 1, 0, 0, 0);
                Calendar wEMTime7 = Calendar.getInstance();
                wEMTime7.set(wYear, 7, 1, 0, 0, 0);
                int month7 = (int) wOrderList.stream()
                        .filter(p -> p.LineID == omsOrder.LineID && p.CustomerID == omsOrder.CustomerID
                                && p.ProductID == omsOrder.ProductID && p.RealFinishDate.compareTo(wSMTime7) >= 0
                                && p.RealFinishDate.compareTo(wEMTime7) < 0)
                        .count();
                // ⑧8月
                Calendar wSMTime8 = Calendar.getInstance();
                wSMTime8.set(wYear, 7, 1, 0, 0, 0);
                Calendar wEMTime8 = Calendar.getInstance();
                wEMTime8.set(wYear, 8, 1, 0, 0, 0);
                int month8 = (int) wOrderList.stream()
                        .filter(p -> p.LineID == omsOrder.LineID && p.CustomerID == omsOrder.CustomerID
                                && p.ProductID == omsOrder.ProductID && p.RealFinishDate.compareTo(wSMTime8) >= 0
                                && p.RealFinishDate.compareTo(wEMTime8) < 0)
                        .count();
                // ⑨9月
                Calendar wSMTime9 = Calendar.getInstance();
                wSMTime9.set(wYear, 8, 1, 0, 0, 0);
                Calendar wEMTime9 = Calendar.getInstance();
                wEMTime9.set(wYear, 9, 1, 0, 0, 0);
                int month9 = (int) wOrderList.stream()
                        .filter(p -> p.LineID == omsOrder.LineID && p.CustomerID == omsOrder.CustomerID
                                && p.ProductID == omsOrder.ProductID && p.RealFinishDate.compareTo(wSMTime9) >= 0
                                && p.RealFinishDate.compareTo(wEMTime9) < 0)
                        .count();
                // ⑩10月
                Calendar wSMTime10 = Calendar.getInstance();
                wSMTime10.set(wYear, 9, 1, 0, 0, 0);
                Calendar wEMTime10 = Calendar.getInstance();
                wEMTime10.set(wYear, 10, 1, 0, 0, 0);
                int month10 = (int) wOrderList.stream()
                        .filter(p -> p.LineID == omsOrder.LineID && p.CustomerID == omsOrder.CustomerID
                                && p.ProductID == omsOrder.ProductID && p.RealFinishDate.compareTo(wSMTime10) >= 0
                                && p.RealFinishDate.compareTo(wEMTime10) < 0)
                        .count();
                // ①11月
                Calendar wSMTime11 = Calendar.getInstance();
                wSMTime11.set(wYear, 10, 1, 0, 0, 0);
                Calendar wEMTime11 = Calendar.getInstance();
                wEMTime11.set(wYear, 11, 1, 0, 0, 0);
                int month11 = (int) wOrderList.stream()
                        .filter(p -> p.LineID == omsOrder.LineID && p.CustomerID == omsOrder.CustomerID
                                && p.ProductID == omsOrder.ProductID && p.RealFinishDate.compareTo(wSMTime11) >= 0
                                && p.RealFinishDate.compareTo(wEMTime11) < 0)
                        .count();
                // ②12月
                Calendar wSMTime12 = Calendar.getInstance();
                wSMTime12.set(wYear, 11, 1, 0, 0, 0);
                Calendar wEMTime12 = Calendar.getInstance();
                wEMTime12.set(wYear, 11, 31, 23, 59, 59);
                int month12 = (int) wOrderList.stream()
                        .filter(p -> p.LineID == omsOrder.LineID && p.CustomerID == omsOrder.CustomerID
                                && p.ProductID == omsOrder.ProductID && p.RealFinishDate.compareTo(wSMTime12) >= 0
                                && p.RealFinishDate.compareTo(wEMTime12) < 0)
                        .count();

                int total = month1 + month2 + month3 + month4 + month5 + month6 + month7 + month8 + month9 + month10
                        + month11 + month12;

                AndonYearFinishSituation wItem = new AndonYearFinishSituation(0, omsOrder.LineID, omsOrder.LineName,
                        omsOrder.CustomerID, omsOrder.Customer, total, month1, month2, month3, month4, month5, month6,
                        month7, month8, month9, month10, month11, month12);
                wItem.ProductNo = omsOrder.ProductNo;
                wTList.add(wItem);
            }
            // ⑤C5
            List<AndonYearFinishSituation> wC5List =
                    wTList.stream().filter(p -> p.LineID == 1).sorted(Comparator.comparing(AndonYearFinishSituation::getCustomerID)).collect(Collectors.toList());
            wResult.CustomResult.put("C5", wC5List);
            // ⑥C6
            List<AndonYearFinishSituation> wC6List =
                    wTList.stream().filter(p -> p.LineID == 2).sorted(Comparator.comparing(AndonYearFinishSituation::getCustomerID)).collect(Collectors.toList());
            wResult.CustomResult.put("C6", wC6List);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<AndonDayReport01> Andon_ProductionDaily1(BMSEmployee wLoginUser, int wYear, int wMonth) {
        ServiceResult<AndonDayReport01> wResult = new ServiceResult<>();
        wResult.Result = new AndonDayReport01();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // ①周计划
            List<Integer> wOrderIDList = APSTaskPartDAO.getInstance().SelectAndonList(wLoginUser, wYear, wMonth,
                    wErrorCode);
            List<APSTaskPart> wList = APSTaskPartDAO.getInstance().SelectListByOrderIDList(wLoginUser,
                    APSShiftPeriod.Week.getValue(), null, wOrderIDList, wErrorCode);

            // ①获取统计数据
            wResult.Result.TJData = AndonDAO.getInstance().Andon_QueryTJData(wLoginUser, wYear, wMonth, wErrorCode);
            // ②获取工位数据
            wResult.Result.PartData = GetPartData(wLoginUser, wYear, wMonth, wList);
            // ①订单查询
            List<OMSOrder> wOrderList = OMSOrderDAO.getInstance().SelectListByIDList(wLoginUser, wOrderIDList,
                    wErrorCode);
            wOrderList.removeIf(p -> p.PartNo.contains("XS") || p.PartNo.contains("GL"));

            // ③获取C5在修车数据
            List<OMSOrder> wC5List = wOrderList.stream().filter(p -> p.LineID == 1 && p.Status == 4)
                    .collect(Collectors.toList());
            int wLineID = 1;
            wResult.Result.C5RepairingList = GetRepairingList(wLoginUser, wC5List, wList, wLineID);
            // ④获取C6在修车数据
            List<OMSOrder> wC6List = wOrderList.stream().filter(p -> p.LineID == 2 && p.Status == 4)
                    .collect(Collectors.toList());
            wLineID = 2;
            wResult.Result.C6RepairingList = GetRepairingList(wLoginUser, wC6List, wList, wLineID);
            // ⑤获取待回送机车数据
            List<OMSOrder> wBackListC5 = wOrderList.stream()
                    .filter(p -> p.LineID == 1 && (p.Status == 5 || p.Status == 6 || p.Status == 7))
                    .collect(Collectors.toList());
            List<AndonDayReportCar> wC5BackList = GetRepairingList(wLoginUser, wBackListC5, wList, 1
            );
            List<OMSOrder> wBackListC6 = wOrderList.stream()
                    .filter(p -> p.LineID == 2 && (p.Status == 5 || p.Status == 6 || p.Status == 7))
                    .collect(Collectors.toList());
            List<AndonDayReportCar> wC6BackList = GetRepairingList(wLoginUser, wBackListC6, wList, 2
            );
            wResult.Result.C5ToBackList = wC5BackList;
            wResult.Result.C6ToBackList = wC6BackList;

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 获取维修中的数据
     */
    private List<AndonDayReportCar> GetRepairingList(BMSEmployee wLoginUser, List<OMSOrder> wC5List,
                                                     List<APSTaskPart> wList, int wLineID) {
        List<AndonDayReportCar> wResult = new ArrayList<>();
        try {
            for (OMSOrder wOMSOrder : wC5List) {
                int stopTime = 0;
                if (wOMSOrder.Status == 4) {
                    stopTime = CalendarUtil.getDayInterval(wOMSOrder.RealReceiveDate.getTime(),
                            Calendar.getInstance().getTime());
                } else {
                    stopTime = CalendarUtil.getDayInterval(wOMSOrder.RealFinishDate.getTime(),
                            Calendar.getInstance().getTime());
                }

                List<AndonDayReportDate> planList = GetPlanReportDateList(wOMSOrder, wLineID, wList);
                List<AndonDayReportDate> realList = GetRealReportDateList(wLoginUser, wOMSOrder, wLineID, wList);
                String remark = GetRemark(wOMSOrder, wLineID, wList);

                AndonDayReportCar wItem = new AndonDayReportCar(wOMSOrder.ProductNo, wOMSOrder.PartNo.split("#")[1],
                        wOMSOrder.LineName, wOMSOrder.Customer, planList, realList, stopTime, remark);
                wResult.add(wItem);
            }
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 获取备注
     */
    private String GetRemark(OMSOrder wOMSOrder, int wLineID, List<APSTaskPart> wList) {
        String wResult = "";
        try {
            List<Integer> wPartIDList = null;
            if (wLineID == 1) {
                wPartIDList = new ArrayList<>(
                        Arrays.asList(103, 28, 64, 27, 53, 11, 22, 21, 20, 43, 5, 2, 163, 59, 107, 26));
            } else if (wLineID == 2) {
                wPartIDList = new ArrayList<>(Arrays.asList(103, 28, 64, 27, 53, 11, 114, 135, 112, 111, 115, 43,
                        5, 161, 160, 159, 163, 59, 107, 26));
            }
            assert wPartIDList != null;
            for (int wPartID : wPartIDList) {
                if (wList.stream().anyMatch(p -> p.OrderID == wOMSOrder.ID && p.LineID == wLineID && p.PartID == wPartID
                        && p.Status == 5)) {
                    wResult = wList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.LineID == wLineID
                            && p.PartID == wPartID && p.Status == 5).findFirst().get().PartName;
                    return wResult;
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 获取实际日期
     */
    private List<AndonDayReportDate> GetRealReportDateList(BMSEmployee wLoginUser, OMSOrder wOMSOrder, int wLineID,
                                                           List<APSTaskPart> wList) {
        List<AndonDayReportDate> wResult = new ArrayList<>();

        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            if (wLineID == 1) {
                // ①入厂
                AndonDayReportDate wDate = new AndonDayReportDate(wOMSOrder.RealReceiveDate, 2);
                wResult.add(wDate);
                // ②机车预检
                int wPartID = 26;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ③机车一级解体
                wPartID = 107;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ④机车外部清洁
                wPartID = 59;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑤转向架解体
                wPartID = 163;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑥机车二级解体
                wPartID = 2;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑦车体检修
                wPartID = 5;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑧车体油漆
                wPartID = 43;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // 上台位
                Calendar wDateTime = AndonDAO.getInstance().Andon_SelectPlaceDate(wLoginUser, wOMSOrder, wErrorCode);
                Calendar wBaseTime = Calendar.getInstance();
                wBaseTime.set(2010, 0, 1, 0, 0, 0);
                if (wDateTime.compareTo(wBaseTime) > 0) {
                    wDate = new AndonDayReportDate(wDateTime, 2);
                } else {
                    wDate = new AndonDayReportDate(wDateTime, 0);
                }
                wResult.add(wDate);
                // ⑨电气检修
                wPartID = 20;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑩机制检修
                wPartID = 0;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ①设备吊装
                wPartID = 21;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ②线管连接
                wPartID = 22;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ③转向架总成
                wPartID = 11;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ④机车总成
                wPartID = 53;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑤低压试验
                wPartID = 27;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑥高压试验
                wPartID = 64;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑦试运
                wPartID = 28;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑧交验
                wPartID = 103;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
            } else if (wLineID == 2) {
                // ①入厂
                AndonDayReportDate wDate = new AndonDayReportDate(wOMSOrder.RealReceiveDate, 2);
                wResult.add(wDate);
                // ②机车预检
                int wPartID = 26;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ③机车一级解体
                wPartID = 107;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ④机车外部清洁
                wPartID = 59;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑤转向架解体
                wPartID = 163;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑥机车二级解体1
                wPartID = 159;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑦机车二级解体2
                wPartID = 160;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑧机车二级解体3
                wPartID = 161;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑨车体检修
                wPartID = 5;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑩车体油漆
                wPartID = 43;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // 上台位
                Calendar wDateTime = AndonDAO.getInstance().Andon_SelectPlaceDate(wLoginUser, wOMSOrder, wErrorCode);
                Calendar wBaseTime = Calendar.getInstance();
                wBaseTime.set(2010, 0, 1, 0, 0, 0);
                if (wDateTime.compareTo(wBaseTime) > 0) {
                    wDate = new AndonDayReportDate(wDateTime, 2);
                } else {
                    wDate = new AndonDayReportDate(wDateTime, 0);
                }
                wResult.add(wDate);
                // ①组装1
                wPartID = 115;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ②组装2
                wPartID = 111;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ③组装3
                wPartID = 112;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ④组装4
                wPartID = 113;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑤组装5
                wPartID = 114;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑥转向架总成
                wPartID = 11;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑦机车总成
                wPartID = 53;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑧低压试验
                wPartID = 27;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑨高压试验
                wPartID = 64;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ⑩试运
                wPartID = 28;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
                // ①交验
                wPartID = 103;
                AddRealTime(wOMSOrder, wList, wResult, wPartID);
            }
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 获取计划日期
     */
    private List<AndonDayReportDate> GetPlanReportDateList(OMSOrder wOMSOrder, int wLineID,
                                                           List<APSTaskPart> wList) {
        List<AndonDayReportDate> wResult = new ArrayList<>();
        try {
            if (wLineID == 1) {
                // ①入厂
                AndonDayReportDate wDate = new AndonDayReportDate(wOMSOrder.TelegraphRealTime, 1);
                wResult.add(wDate);
                // ②机车预检
                int wPartID = 26;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ③机车一级解体
                wPartID = 107;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ④机车外部清洁
                wPartID = 59;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑤转向架解体
                wPartID = 163;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑥机车二级解体
                wPartID = 2;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑦车体检修
                wPartID = 5;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑧车体油漆
                wPartID = 43;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);

                // 上台位
                Calendar wBaseTime = Calendar.getInstance();
                wBaseTime.set(2000, 0, 1, 0, 0, 0);
                wDate = new AndonDayReportDate(wBaseTime, 1);
                wResult.add(wDate);

                // ⑨电气检修
                wPartID = 20;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑩机制检修
                wPartID = 0;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ①设备吊装
                wPartID = 21;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ②线管连接
                wPartID = 22;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ③转向架总成
                wPartID = 11;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ④机车总成
                wPartID = 53;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑤低压试验
                wPartID = 27;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑥高压试验
                wPartID = 64;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑦试运
                wPartID = 28;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑧交验
                wPartID = 103;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
            } else if (wLineID == 2) {
                // ①入厂
                AndonDayReportDate wDate = new AndonDayReportDate(wOMSOrder.RealReceiveDate, 1);
                wResult.add(wDate);
                // ②机车预检
                int wPartID = 26;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ③机车一级解体
                wPartID = 107;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ④机车外部清洁
                wPartID = 59;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑤转向架解体
                wPartID = 163;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑥机车二级解体1
                wPartID = 159;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑦机车二级解体2
                wPartID = 160;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑧机车二级解体3
                wPartID = 161;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑨车体检修
                wPartID = 5;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑩车体油漆
                wPartID = 43;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // 上台位
                Calendar wBaseTime = Calendar.getInstance();
                wBaseTime.set(2000, 0, 1, 0, 0, 0);
                wDate = new AndonDayReportDate(wBaseTime, 1);
                wResult.add(wDate);
                // ①组装1
                wPartID = 115;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ②组装2
                wPartID = 111;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ③组装3
                wPartID = 112;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ④组装4
                wPartID = 113;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑤组装5
                wPartID = 114;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑥转向架总成
                wPartID = 11;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑦机车总成
                wPartID = 53;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑧低压试验
                wPartID = 27;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑨高压试验
                wPartID = 64;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ⑩试运
                wPartID = 28;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
                // ①交验
                wPartID = 103;
                AddPlanTime(wOMSOrder, wList, wResult, wPartID);
            }
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 添加计划时间
     */
    private void AddPlanTime(OMSOrder wOMSOrder, List<APSTaskPart> wList, List<AndonDayReportDate> wResult,
                             int wPartID) {
        try {
            if (wList.stream().anyMatch(p -> p.OrderID == wOMSOrder.ID && p.PartID == wPartID)) {
                APSTaskPart apsTaskPart = wList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.PartID == wPartID)
                        .findFirst().get();
                AndonDayReportDate wDateTime = new AndonDayReportDate(apsTaskPart.EndTime, 1);
                wResult.add(wDateTime);
            } else {
                Calendar wBaseTime = Calendar.getInstance();
                wBaseTime.set(2000, 0, 1, 0, 0, 0);

                AndonDayReportDate wDateTime = new AndonDayReportDate(wBaseTime, 0);
                wResult.add(wDateTime);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 添加实际时间
     */
    private void AddRealTime(OMSOrder wOMSOrder, List<APSTaskPart> wList, List<AndonDayReportDate> wResult,
                             int wPartID) {
        try {
            if (wList.stream().anyMatch(p -> p.OrderID == wOMSOrder.ID && p.PartID == wPartID)) {
                APSTaskPart apsTaskPart = wList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.PartID == wPartID)
                        .findFirst().get();

                if (apsTaskPart.Status == 5) {

                    Calendar wEndTime = (Calendar) apsTaskPart.EndTime.clone();
                    wEndTime.add(Calendar.HOUR_OF_DAY, -12);

                    SimpleDateFormat wSDF = new SimpleDateFormat("yyyyMMdd");
                    int wPShiftID = Integer.parseInt(wSDF.format(wEndTime.getTime()));
                    int wRShiftID = Integer.parseInt(wSDF.format(apsTaskPart.FinishWorkTime.getTime()));

                    AndonDayReportDate wDateTime;
                    if (wRShiftID > wPShiftID) {
                        wDateTime = new AndonDayReportDate(apsTaskPart.FinishWorkTime, 3);
                    } else {
                        wDateTime = new AndonDayReportDate(apsTaskPart.FinishWorkTime, 2);
                    }
                    wResult.add(wDateTime);
                } else {
                    AndonDayReportDate wDateTime = new AndonDayReportDate(apsTaskPart.FinishWorkTime, 0);
                    wResult.add(wDateTime);
                }
            } else {
                Calendar wBaseTime = Calendar.getInstance();
                wBaseTime.set(2000, 0, 1, 0, 0, 0);

                AndonDayReportDate wDateTime = new AndonDayReportDate(wBaseTime, 0);
                wResult.add(wDateTime);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 获取工位数据
     */
    private AndonDayReportPart GetPartData(BMSEmployee wLoginUser, int wYear, int wMonth, List<APSTaskPart> wList) {
        AndonDayReportPart wResult = new AndonDayReportPart();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // ①C5
            // ①入厂
            int wLineID = 1;
            int wRC = AndonDAO.getInstance().Andon_SelectRC(wLoginUser, wYear, wMonth, wLineID, wErrorCode);
            wResult.C5Plan.add(0);
            wResult.C5Real.add(wRC);
            wResult.C5Out.add(0);
            // ②机车预检
            int wPartID = 26;
            AddData(wResult, wList, wLineID, wPartID);
            // ③机车一级解体
            wPartID = 107;
            AddData(wResult, wList, wLineID, wPartID);
            // ④机车外部清洁
            wPartID = 59;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑤转向架解体
            wPartID = 163;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑥机车二级解体
            wPartID = 2;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑦车体检修
            wPartID = 5;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑧车体油漆
            wPartID = 43;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑨上台位

            List<Integer> wOrderIDList = wList.stream().filter(p -> p.LineID == 1).map(p -> p.OrderID).distinct()
                    .collect(Collectors.toList());
            int wNumber = AndonDAO.getInstance().Andon_SelectPlaceNumber(wLoginUser, wOrderIDList, wErrorCode);

            wResult.C5Plan.add(0);
            wResult.C5Real.add(wNumber);
            wResult.C5Out.add(0);
            // ⑩电气检修
            wPartID = 20;
            AddData(wResult, wList, wLineID, wPartID);
            // ①机制检修
            wResult.C5Plan.add(0);
            wResult.C5Real.add(0);
            wResult.C5Out.add(0);
            // ②设备吊装
            wPartID = 21;
            AddData(wResult, wList, wLineID, wPartID);
            // ③线管连接
            wPartID = 22;
            AddData(wResult, wList, wLineID, wPartID);
            // ④转向架总成
            wPartID = 11;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑤机车总成
            wPartID = 53;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑥低压试验
            wPartID = 27;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑦高压试验
            wPartID = 64;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑧试运
            wPartID = 28;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑨交验
            wPartID = 103;
            AddData(wResult, wList, wLineID, wPartID);
            // ②C6
            // ①入厂
            wLineID = 2;
            wRC = AndonDAO.getInstance().Andon_SelectRC(wLoginUser, wYear, wMonth, wLineID, wErrorCode);
            wResult.C6Plan.add(0);
            wResult.C6Real.add(wRC);
            wResult.C6Out.add(0);
            // ②机车预检
            wPartID = 26;
            AddData(wResult, wList, wLineID, wPartID);
            // ③机车一级解体
            wPartID = 107;
            AddData(wResult, wList, wLineID, wPartID);
            // ④机车外部清洁
            wPartID = 59;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑤转向架解体
            wPartID = 163;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑥机车二级解体1
            wPartID = 159;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑦机车二级解体2
            wPartID = 160;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑧机车二级解体3
            wPartID = 161;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑨车体检修
            wPartID = 5;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑩车体油漆
            wPartID = 43;
            AddData(wResult, wList, wLineID, wPartID);
            // ①上台位
            wOrderIDList = wList.stream().filter(p -> p.LineID == 2).map(p -> p.OrderID).distinct()
                    .collect(Collectors.toList());
            wNumber = AndonDAO.getInstance().Andon_SelectPlaceNumber(wLoginUser, wOrderIDList, wErrorCode);

            wResult.C6Plan.add(0);
            wResult.C6Real.add(wNumber);
            wResult.C6Out.add(0);
            // ②组装1
            wPartID = 115;
            AddData(wResult, wList, wLineID, wPartID);
            // ③组装2
            wPartID = 111;
            AddData(wResult, wList, wLineID, wPartID);
            // ④组装3
            wPartID = 112;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑤组装4
            wPartID = 113;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑥组长5
            wPartID = 114;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑦转向架总成
            wPartID = 11;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑧机车总成
            wPartID = 53;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑨低压试验
            wPartID = 27;
            AddData(wResult, wList, wLineID, wPartID);
            // ⑩高压试验
            wPartID = 64;
            AddData(wResult, wList, wLineID, wPartID);
            // ①试运
            wPartID = 28;
            AddData(wResult, wList, wLineID, wPartID);
            // ②交验
            wPartID = 103;
            AddData(wResult, wList, wLineID, wPartID);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 添加数据
     */
    private void AddData(AndonDayReportPart wResult, List<APSTaskPart> wList, int wLineID, int wPartID) {
        try {
            int wPlanNumber;
            int wRealNum;
            int wOut;
            wPlanNumber = (int) wList.stream().filter(p -> p.LineID == wLineID && p.PartID == wPartID)
                    .map(p -> p.OrderID).distinct().count();
            wRealNum = (int) wList.stream().filter(p -> p.LineID == wLineID && p.PartID == wPartID && p.Status == 5)
                    .map(p -> p.OrderID).distinct().count();
            wOut = Math.max(wPlanNumber - wRealNum, 0);
            if (wLineID == 1) {
                wResult.C5Plan.add(wPlanNumber);
                wResult.C5Real.add(wRealNum);
                wResult.C5Out.add(wOut);
            } else {
                wResult.C6Plan.add(wPlanNumber);
                wResult.C6Real.add(wRealNum);
                wResult.C6Out.add(wOut);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    @Override
    public ServiceResult<String> Andon_ExportProductionPlan(BMSEmployee wLoginUser) {
        ServiceResult<String> wResult = new ServiceResult<>();
        wResult.Result = "";
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // ①周计划
            List<OMSOrder> wOrderList = OMSServiceImpl.getInstance()
                    .OMS_QueryOMSOrderList(wLoginUser, -1, -1, "", -1, -1, -1, "", "", 1,
                            StringUtils.parseListArgs(OMSOrderStatus.ReceivedTelegraph.getValue(),
                                    OMSOrderStatus.EnterFactoryed.getValue(), OMSOrderStatus.Repairing.getValue(),
                                    OMSOrderStatus.FinishedWork.getValue(), OMSOrderStatus.ToOutChcek.getValue(),
                                    OMSOrderStatus.ToOutConfirm.getValue()))
                    .getResult();

            // 移除实际进厂时间在2021-8-29 00:00:00之前的订单
            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2021, 7, 29, 0, 0, 0);
            wOrderList.removeIf(p -> p.RealReceiveDate.compareTo(wBaseTime) < 0);

            wOrderList.removeIf(p -> p.Active != 1 || p.ID <= 0);
            if (wOrderList.size() <= 0) {
                wResult.FaultCode += "无在修订单";
                return wResult;
            }

            // 订单排序
            wOrderList.sort(Comparator.comparing(OMSOrder::getERPID).thenComparing(OMSOrder::getRealReceiveDate));

            List<Integer> wOrderIDListTemp = wOrderList.stream().map(p -> p.ID).distinct().collect(Collectors.toList());

            List<APSTaskPart> wTaskPartList = APSServiceImpl.getInstance()
                    .APS_QueryTaskPartList(wLoginUser, APSShiftPeriod.Week.getValue(), null, wOrderIDListTemp)
                    .getResult();

            if (wTaskPartList == null || wTaskPartList.size() <= 0) {
                wResult.FaultCode += "无在修任务";
                return wResult;
            }

            // 工序计划排序
            wTaskPartList = OrderTaskPart(wTaskPartList, wOrderList);

            // 剔除没有任务的订单
            List<APSTaskPart> wAPSTaskPartClone = wTaskPartList;
            wOrderList.removeIf(p -> wAPSTaskPartClone.stream().noneMatch(q -> q.OrderID == p.ID));

            List<Integer> wOrderIDList = wTaskPartList.stream().map(p -> p.OrderID).distinct()
                    .collect(Collectors.toList());
            // ①主计划pagenumber=1
            List<LFSWorkAreaStation> wWSList = APSConstans.GetLFSWorkAreaStationList().values().stream()
                    .filter(p -> p.Active == 1).sorted(Comparator.comparing(LFSWorkAreaStation::getOrderNum)).collect(Collectors.toList());

            // 排序
            for (APSTaskPart wAPSTaskPart : wTaskPartList) {
                if (wWSList.stream().anyMatch(p -> p.StationID == wAPSTaskPart.PartID)) {
                    wAPSTaskPart.PartOrder = wWSList.stream().filter(p -> p.StationID == wAPSTaskPart.PartID)
                            .findFirst().get().OrderNum;
                }
            }
            wTaskPartList.sort(Comparator.comparing(APSTaskPart::getPartOrder));

            List<Integer> wMainPartIDList = wWSList.stream().filter(p -> p.PageNumber == 1).map(p -> p.StationID)
                    .distinct().collect(Collectors.toList());

            List<Integer> wMainPartIDListFilter = wTaskPartList.stream()
                    .filter(p -> wMainPartIDList.stream().anyMatch(q -> q == p.PartID)).map(p -> p.PartID).distinct()
                    .collect(Collectors.toList());

            // ②部件pagenumber=2
            List<Integer> wPartPartIDList = wWSList.stream().filter(p -> p.PageNumber == 4).map(p -> p.StationID)
                    .distinct().collect(Collectors.toList());

            List<Integer> wPartPartIDListFilter = wTaskPartList.stream()
                    .filter(p -> wPartPartIDList.stream().anyMatch(q -> q == p.PartID)).map(p -> p.PartID).distinct()
                    .collect(Collectors.toList());

            // ③驱动pagenumber=3
            List<Integer> wDrivePartIDList = wWSList.stream().filter(p -> p.PageNumber == 2).map(p -> p.StationID)
                    .distinct().collect(Collectors.toList());
            List<Integer> wDrivePartIDListFilter = wTaskPartList.stream()
                    .filter(p -> wDrivePartIDList.stream().anyMatch(q -> q == p.PartID)).map(p -> p.PartID).distinct()
                    .collect(Collectors.toList());

            // ④变压器pagenumber=4
            List<Integer> wTransformerPartIDList = wWSList.stream().filter(p -> p.PageNumber == 3).map(p -> p.StationID)
                    .distinct().collect(Collectors.toList());
            List<Integer> wTransformerPartIDListFilter = wTaskPartList.stream()
                    .filter(p -> wTransformerPartIDList.stream().anyMatch(q -> q == p.PartID)).map(p -> p.PartID)
                    .distinct().collect(Collectors.toList());

            // ②工序计划
            List<Integer> wStepPartList = new ArrayList<>();
            wStepPartList.addAll(wPartPartIDList);
            wStepPartList.addAll(wDrivePartIDList);
            wStepPartList.addAll(wTransformerPartIDList);
            List<APSTaskStepPlan> wStepPlanList = APSServiceImpl.getInstance().APS_QueryStepPlanCompare(wLoginUser,
                    StringUtils.Join(",", wOrderIDList), StringUtils.Join(",", wStepPartList),
                    APSShiftPeriod.Week.getValue()).Result;

            // 工序计划排序
            wStepPlanList = OrderTaskStepPlan(wStepPlanList, wOrderList);

            // ③导出
            wResult.Result = ExcelUtil.ExportProductPlan(wLoginUser, wTaskPartList, wStepPlanList,
                    wMainPartIDListFilter, wPartPartIDListFilter, wDrivePartIDListFilter, wTransformerPartIDListFilter,
                    wOrderList);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    private List<APSTaskPart> OrderTaskPart(List<APSTaskPart> wTaskPartList, List<OMSOrder> wOrderList) {
        List<APSTaskPart> wResult = new ArrayList<>();
        try {
            if (wTaskPartList == null || wTaskPartList.size() <= 0) {
                return wResult;
            }

            for (OMSOrder wOMSOrder : wOrderList) {
                List<APSTaskPart> wList = wTaskPartList.stream().filter(p -> p.OrderID == wOMSOrder.ID)
                        .collect(Collectors.toList());
                if (wList.size() > 0) {
                    wResult.addAll(wList);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    private List<APSTaskStepPlan> OrderTaskStepPlan(List<APSTaskStepPlan> wStepPlanList, List<OMSOrder> wOrderList) {
        List<APSTaskStepPlan> wResult = new ArrayList<>();
        try {
            if (wStepPlanList == null || wStepPlanList.size() <= 0) {
                return wResult;
            }

            for (OMSOrder wOMSOrder : wOrderList) {
                List<APSTaskStepPlan> wList = wStepPlanList.stream().filter(p -> p.OrderID == wOMSOrder.ID)
                        .collect(Collectors.toList());
                if (wList.size() > 0) {
                    wResult.addAll(wList);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<AndonTaskStep>> Andon_QueryAreaStepDetails(BMSEmployee wLoginUser, int wStatus,
                                                                         int wWorkAreaID, Calendar wStartTime,
                                                                         Calendar wEndTime, int wOrderID,
                                                                         int wPartID, int wStepID) {
        ServiceResult<List<AndonTaskStep>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wEndTime.set(Calendar.HOUR_OF_DAY, 23);
            wEndTime.set(Calendar.MINUTE, 59);
            wEndTime.set(Calendar.SECOND, 59);

            List<AndonTaskStep> wList = AndonDAO.getInstance().SelectAreaStepDetails(wLoginUser, wStatus, wWorkAreaID,
                    wStartTime, wEndTime, wErrorCode);

            // 班组工位
            List<FMCWorkCharge> wWorkCharegeList = APSConstans.GetFMCWorkChargeList();
            for (AndonTaskStep wAndonTaskStep : wList) {
                List<FMCWorkCharge> wItemList = wWorkCharegeList.stream()
                        .filter(p -> p.StationID == wAndonTaskStep.PartID).collect(Collectors.toList());
                if (wItemList.size() > 0) {
                    List<String> wNames = wItemList.stream().map(p -> p.ClassName).collect(Collectors.toList());
                    wAndonTaskStep.ClassNames = StringUtils.Join(",", wNames);
                }
            }

            List<Integer> wOrderIDList = wList.stream().map(p -> p.OrderID).distinct().collect(Collectors.toList());
            List<OMSOrder> wOrderList = OMSOrderDAO.getInstance().SelectListByIDList(wLoginUser, wOrderIDList,
                    wErrorCode);
            wOrderList.sort(Comparator.comparing(OMSOrder::getERPID).thenComparing(OMSOrder::getRealReceiveDate));
            for (OMSOrder omsOrder : wOrderList) {
                List<AndonTaskStep> wTempList = wList.stream().filter(p -> p.OrderID == omsOrder.ID)
                        .collect(Collectors.toList());
                wResult.Result.addAll(wTempList);
            }
            // 工位排序
            Map<Integer, Integer> wOrderMap = AndonDAO.getInstance().Andon_QueryPartOrderMap(wLoginUser,
                    wOrderList.get(0).RouteID, wErrorCode);
            for (AndonTaskStep wAndonTaskStep : wResult.Result) {
                if (wOrderMap.containsKey(wAndonTaskStep.PartID)) {
                    wAndonTaskStep.OrderNum = wOrderMap.get(wAndonTaskStep.PartID);
                }
            }
            wResult.Result
                    .sort(Comparator.comparing(AndonTaskStep::getOrderNum).thenComparing(AndonTaskStep::getPartID));

            // 条件筛选
            if (wOrderID > 0) {
                wResult.Result = wResult.Result.stream().filter(p -> p.OrderID == wOrderID)
                        .collect(Collectors.toList());
            }
            if (wPartID > 0) {
                wResult.Result = wResult.Result.stream().filter(p -> p.PartID == wPartID).collect(Collectors.toList());
            }
            if (wStepID > 0) {
                wResult.Result = wResult.Result.stream().filter(p -> p.StepID == wStepID).collect(Collectors.toList());
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> Andon_QueryPickDemandDataAndon(BMSEmployee wLoginUser) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            //今日时间
            Calendar wSTime = Calendar.getInstance();
            wSTime.set(wSTime.get(Calendar.YEAR), wSTime.get(Calendar.MONTH), wSTime.get(Calendar.DATE), 0, 0, 0);

            Calendar wETime = Calendar.getInstance();
            wETime.set(wSTime.get(Calendar.YEAR), wSTime.get(Calendar.MONTH), wSTime.get(Calendar.DATE), 23, 59, 59);
            //①分拣完成的数据集合
            List<Integer> wPickFinishedIDList = WMSPickDemandDAO.getInstance().SelectPickFinishedIDList(wLoginUser,
                    wSTime, wETime, wErrorCode);
            List<WMSPickDemand> wSortList = WMSPickDemandDAO.getInstance().SelectList(wLoginUser, -1,
                    "", "", -1, -1,
                    -1, "", -1, -1, null, null, wPickFinishedIDList, wErrorCode);
            wResult.CustomResult.put("SortList", wSortList);
            wResult.CustomResult.put("SortSize", wSortList.size());
            wResult.CustomResult.put("SortFinishedSize",
                    (int) wSortList.stream().filter(p -> p.Status == 4).count());
            //②配送中的数据集合
            List<Integer> wSendFinishedIDList = WMSPickDemandDAO.getInstance().SelectSendFinishedIDList(wLoginUser,
                    wSTime, wETime, wErrorCode);
            List<WMSPickDemand> wSendList = new ArrayList<>();
            if (wSendFinishedIDList.size() > 0) {
                wSendList = WMSPickDemandDAO.getInstance().SelectList(wLoginUser, -1,
                        "", "", -1, -1,
                        -1, "", -1, -1, null, null, wSendFinishedIDList, wErrorCode);
            }

            wResult.CustomResult.put("SendList", wSendList);
            wResult.CustomResult.put("SendSize", wSendList.size());
            wResult.CustomResult.put("SendFinishedSize",
                    (int) wSendList.stream().filter(p -> p.Status == 5).count());

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<OrderTimeInfo>> Andon_QueryTrainOrderInfoListNew_V2(BMSEmployee wLoginUser) {
        ServiceResult<List<OrderTimeInfo>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            //①查询在厂台车列表，根据实际进厂时间升序排序
            //①获取台位列表
            List<FMCWorkspace> wFMCWorkspaceList = FMCServiceImpl.getInstance().FMC_GetFMCWorkspaceList(wLoginUser,
                    -1, -1, "", -1
                    , 1).List(FMCWorkspace.class);
            //①获取库位列表
            List<LFSStoreHouse> wLFSStoreHouseList =
                    LFSServiceImpl.getInstance().LFS_QueryStoreHouseList(wLoginUser).List(LFSStoreHouse.class).stream().
                            filter(p -> p.Active == 1).collect(Collectors.toList());
            // ①获取有周计划，维修中的订单ID集合
            List<Integer> wIDList = OMSOrderDAO.getInstance().SelectIDListByWeekPlan(wLoginUser, wErrorCode);
            // ①根据订单ID集合，查询维修中的订单
            List<OMSOrder> wOrderList = OMSOrderDAO.getInstance().SelectListByIDList(wLoginUser, wIDList, wErrorCode);
            if (wOrderList == null || wOrderList.size() <= 0) {
                return wResult;
            }
            // 排序
            wOrderList.sort(Comparator.comparing(OMSOrder::getRealReceiveDate));
            // 获取车体工位集合
            List<Integer> wBodyStationIDList = AndonDAO.getInstance().Andon_GetBodyStationIDList(wLoginUser,
                    wErrorCode);
            //②根据在厂台车查询转序任务列表
            List<RSMTurnOrderTask> wRSMTurnOrderTaskList =
                    AndonDAO.getInstance().Andon_QueryTurnOrderTaskByOrderIDList(wLoginUser, wIDList, wErrorCode);
            //提取所有工位
            List<Integer> wPartIDList = new ArrayList<>();
            for (RSMTurnOrderTask wRSMTurnOrderTask : wRSMTurnOrderTaskList) {
                if (wPartIDList.stream().noneMatch(p -> p == wRSMTurnOrderTask.ApplyStationID)) {
                    wPartIDList.add(wRSMTurnOrderTask.ApplyStationID);
                }
                if (wPartIDList.stream().noneMatch(p -> p == wRSMTurnOrderTask.TargetStationID)) {
                    wPartIDList.add(wRSMTurnOrderTask.TargetStationID);
                }
            }
            wPartIDList = wPartIDList.stream().distinct().collect(Collectors.toList());
            //③根据在厂台车查询工位任务列表(周计划)
            List<APSTaskPart> wAPSTaskPartList =
                    AndonDAO.getInstance().Andon_QueryTaskPartListByOrderIDListAndPartIDList(wLoginUser, wIDList,
                            wPartIDList, wErrorCode);
            //③根据在厂台车、工位查询工序任务列表
            List<APSTaskStep> wAPSTaskStepList =
                    AndonDAO.getInstance().Andon_QueryTaskStepListByOrderIDListAndPartIDList(wLoginUser, wIDList,
                            wPartIDList, wErrorCode);
            //④根据在厂台车、工位查询返修数列表
            List<RROItemTask> wRROItemTaskList =
                    AndonDAO.getInstance().Andon_QueryRROItemTaskListByOrderIDListAndPartIDList(wLoginUser, wIDList,
                            wPartIDList, wErrorCode);
            //⑤根据在厂台车、工位查询不合格评审单列表
            List<NCRTask> wNCRTaskList =
                    AndonDAO.getInstance().Andon_QueryNCRTaskListByOrderIDListAndPartIDList(wLoginUser, wIDList,
                            wPartIDList, wErrorCode);
            //⑥根据在厂台车查询异常列表
            List<EXCCallTaskBPM> wEXCCallTaskBPMList =
                    AndonDAO.getInstance().Andon_QueryEXCCallTaskBPMListByOrderIDList(wLoginUser, wIDList, wErrorCode);
            SimpleDateFormat wSDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //⑥遍历在厂台车、转序任务目标工位，组装数据返回前端
            for (OMSOrder wOMSOrder : wOrderList) {
                List<RSMTurnOrderTask> wOrderRSMTurnOrderTaskList =
                        wRSMTurnOrderTaskList.stream().filter(p -> p.OrderID == wOMSOrder.ID).collect(Collectors.toList());
                if (wOrderRSMTurnOrderTaskList.size() > 0) {
                    List<Integer> wStationIDList = AndonDAO.getInstance().QueryCurrentStationList_V3(wLoginUser,
                            wOrderRSMTurnOrderTaskList, wErrorCode);
                    for (int wPartID : wStationIDList) {
                        // 不是车体工位直接继续
                        if (wBodyStationIDList.stream().noneMatch(p -> p == wPartID)) {
                            continue;
                        }
                        OrderTimeInfo wOrderTimeInfo = new OrderTimeInfo();

                        wOrderTimeInfo.CustomerName = wOMSOrder.Customer;
                        wOrderTimeInfo.ExcNum =
                                (int) wEXCCallTaskBPMList.stream().filter(p -> p.OrderID == wOMSOrder.ID && (p.StationID == wPartID)).count();
                        wOrderTimeInfo.FinishNum =
                                (int) wAPSTaskStepList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.PartID == wPartID && p.Status == 5).count();
                        wOrderTimeInfo.InPlantTime = wOMSOrder.RealReceiveDate;
                        wOrderTimeInfo.LineName = wOMSOrder.LineName;
                        wOrderTimeInfo.NcrNum =
                                (int) wNCRTaskList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.StationID == wPartID).count();
                        wOrderTimeInfo.OrderID = wOMSOrder.ID;
                        wOrderTimeInfo.PartNo = wOMSOrder.PartNo;
                        wOrderTimeInfo.PlaceName = "";

                        String wPartNoNumber = wOMSOrder.PartNo.split("#")[1];
                        if (wFMCWorkspaceList.stream().anyMatch(p -> p.PartNo.contains(wPartNoNumber))) {
                            FMCWorkspace wFMCWorkspace =
                                    wFMCWorkspaceList.stream().filter(p -> p.PartNo.contains(wPartNoNumber)).findFirst().get();
                            wOrderTimeInfo.PlaceName = wFMCWorkspace.Name;
                            if (wLFSStoreHouseList.stream().anyMatch(p -> p.ID == wFMCWorkspace.ParentID)) {
                                LFSStoreHouse wLFSStoreHouse =
                                        wLFSStoreHouseList.stream().filter(p -> p.ID == wFMCWorkspace.ParentID).findFirst().get();
                                wOrderTimeInfo.StockName = wLFSStoreHouse.Name;
                            }
                        }

                        wOrderTimeInfo.RealReceiveDate = wSDF.format(wOMSOrder.RealReceiveDate.getTime());
                        wOrderTimeInfo.ReworkNum =
                                (int) wRROItemTaskList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.StationID == wPartID).count();
                        //查找工位任务
                        if (wAPSTaskPartList.stream().anyMatch(p -> p.OrderID == wOMSOrder.ID && p.PartID == wPartID)) {
                            APSTaskPart wAPSTaskPart =
                                    wAPSTaskPartList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.PartID == wPartID).findFirst().get();
                            wOrderTimeInfo.StationName = wAPSTaskPart.PartName;
                            int wStatus = wAPSTaskPart.Status;
                            wOrderTimeInfo.Status = "未开工";
                            if (wStatus == 5) {
                                wOrderTimeInfo.Status = "工位完工";
                            } else if (wStatus == 4) {
                                wOrderTimeInfo.Status = "工位开工";
                            }
                            //处理数据
                            wOrderTimeInfo.PlanStartTime = wAPSTaskPart.StartTime;
                            wOrderTimeInfo.PlanEndTime = wAPSTaskPart.EndTime;
                            wOrderTimeInfo.PlanEndTime.add(Calendar.HOUR_OF_DAY, -12);

                            wOrderTimeInfo.PlanSituation = CalendarUtil.getDayInterval(wAPSTaskPart.StartTime.getTime(),
                                    Calendar.getInstance().getTime());

                            SimpleDateFormat wSDF1 = new SimpleDateFormat("yyyyMMdd");
                            int wShiftID = Integer.parseInt(wSDF1.format(wOrderTimeInfo.PlanStartTime.getTime()));
                            int wTShiftID = Integer.parseInt(wSDF1.format(Calendar.getInstance().getTime()));

                            switch (wOrderTimeInfo.Status) {
                                case "未开工":
                                    if (wShiftID == wTShiftID) {
                                        wOrderTimeInfo.StationColor = 2;
                                    } else if (wShiftID > wTShiftID) {
                                        wOrderTimeInfo.StationColor = 3;
                                    } else {
                                        wOrderTimeInfo.StationColor = 2;
                                    }
                                    break;
                                case "工位开工":
                                    if (wShiftID >= wTShiftID) {
                                        wOrderTimeInfo.StationColor = 1;
                                    } else {
                                        wOrderTimeInfo.StationColor = 2;
                                    }
                                    break;
                                case "工位完工":
                                    wOrderTimeInfo.StationColor = 4;
                                    break;
                                case "异常":
                                    wOrderTimeInfo.StationColor = 3;
                                    break;

                                default:
                                    break;
                            }
                        }
                        if (wOrderTimeInfo.ExcNum > 0) {
                            wOrderTimeInfo.Status = "异常";
                        }

                        wOrderTimeInfo.StopTime = wOMSOrder.StopTime;
                        wOrderTimeInfo.StopTime = CalendarUtil.getDayInterval(wOMSOrder.RealReceiveDate.getTime(),
                                Calendar.getInstance().getTime());
                        int wTotalNum =
                                (int) wAPSTaskStepList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.PartID == wPartID).count();
                        wOrderTimeInfo.SurplusNum = wTotalNum - wOrderTimeInfo.FinishNum;
                        wOrderTimeInfo.STTotal =
                                (int) wAPSTaskPartList.stream().filter(p -> p.OrderID == wOMSOrder.ID).count();
                        wOrderTimeInfo.STFinish =
                                (int) wAPSTaskPartList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.Status == 5).count();
                        wResult.Result.add(wOrderTimeInfo);
                    }
                } else {
                    //预检任务
                    List<Integer> wStationIDList = new ArrayList<>(Collections.singletonList(26));
                    for (int wPartID : wStationIDList) {
                        // 不是车体工位直接继续
                        if (wBodyStationIDList.stream().noneMatch(p -> p == wPartID)) {
                            continue;
                        }
                        OrderTimeInfo wOrderTimeInfo = new OrderTimeInfo();

                        wOrderTimeInfo.CustomerName = wOMSOrder.Customer;
                        wOrderTimeInfo.ExcNum =
                                (int) wEXCCallTaskBPMList.stream().filter(p -> p.OrderID == wOMSOrder.ID && (p.StationID == wPartID)).count();
                        wOrderTimeInfo.FinishNum =
                                (int) wAPSTaskStepList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.PartID == wPartID && p.Status == 5).count();
                        wOrderTimeInfo.InPlantTime = wOMSOrder.RealReceiveDate;
                        wOrderTimeInfo.LineName = wOMSOrder.LineName;
                        wOrderTimeInfo.NcrNum =
                                (int) wNCRTaskList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.StationID == wPartID).count();
                        wOrderTimeInfo.OrderID = wOMSOrder.ID;
                        wOrderTimeInfo.PartNo = wOMSOrder.PartNo;
                        wOrderTimeInfo.PlaceName = "";

                        String wPartNoNumber = wOMSOrder.PartNo.split("#")[1];
                        if (wFMCWorkspaceList.stream().anyMatch(p -> p.PartNo.contains(wPartNoNumber))) {
                            FMCWorkspace wFMCWorkspace =
                                    wFMCWorkspaceList.stream().filter(p -> p.PartNo.contains(wPartNoNumber)).findFirst().get();
                            wOrderTimeInfo.PlaceName = wFMCWorkspace.Name;
                            if (wLFSStoreHouseList.stream().anyMatch(p -> p.ID == wFMCWorkspace.ParentID)) {
                                LFSStoreHouse wLFSStoreHouse =
                                        wLFSStoreHouseList.stream().filter(p -> p.ID == wFMCWorkspace.ParentID).findFirst().get();
                                wOrderTimeInfo.StockName = wLFSStoreHouse.Name;
                            }
                        }

                        wOrderTimeInfo.RealReceiveDate = wSDF.format(wOMSOrder.RealReceiveDate.getTime());
                        wOrderTimeInfo.ReworkNum =
                                (int) wRROItemTaskList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.StationID == wPartID).count();
                        wOrderTimeInfo.StationName = "机车预检";
                        //查找工位任务
                        if (wAPSTaskPartList.stream().anyMatch(p -> p.OrderID == wOMSOrder.ID && p.PartID == wPartID)) {
                            APSTaskPart wAPSTaskPart =
                                    wAPSTaskPartList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.PartID == wPartID).findFirst().get();
                            wOrderTimeInfo.StationName = wAPSTaskPart.PartName;
                            int wStatus = wAPSTaskPart.Status;
                            wOrderTimeInfo.Status = "未开工";
                            if (wStatus == 5) {
                                wOrderTimeInfo.Status = "工位完工";
                            } else if (wStatus == 4) {
                                wOrderTimeInfo.Status = "工位开工";
                            }

                            //处理数据
                            wOrderTimeInfo.PlanStartTime = wAPSTaskPart.StartTime;
                            wOrderTimeInfo.PlanEndTime = wAPSTaskPart.EndTime;
                            wOrderTimeInfo.PlanEndTime.add(Calendar.HOUR_OF_DAY, -12);

                            wOrderTimeInfo.PlanSituation = CalendarUtil.getDayInterval(wAPSTaskPart.StartTime.getTime(),
                                    Calendar.getInstance().getTime());

                            SimpleDateFormat wSDF1 = new SimpleDateFormat("yyyyMMdd");
                            int wShiftID = Integer.parseInt(wSDF1.format(wOrderTimeInfo.PlanStartTime.getTime()));
                            int wTShiftID = Integer.parseInt(wSDF1.format(Calendar.getInstance().getTime()));

                            switch (wOrderTimeInfo.Status) {
                                case "未开工":
                                    if (wShiftID == wTShiftID) {
                                        wOrderTimeInfo.StationColor = 2;
                                    } else if (wShiftID > wTShiftID) {
                                        wOrderTimeInfo.StationColor = 3;
                                    } else {
                                        wOrderTimeInfo.StationColor = 2;
                                    }
                                    break;
                                case "工位开工":
                                    if (wShiftID >= wTShiftID) {
                                        wOrderTimeInfo.StationColor = 1;
                                    } else {
                                        wOrderTimeInfo.StationColor = 2;
                                    }
                                    break;
                                case "工位完工":
                                    wOrderTimeInfo.StationColor = 4;
                                    break;
                                case "异常":
                                    wOrderTimeInfo.StationColor = 3;
                                    break;

                                default:
                                    break;
                            }
                        }
                        if (wOrderTimeInfo.ExcNum > 0) {
                            wOrderTimeInfo.Status = "异常";
                        }

                        wOrderTimeInfo.StopTime = wOMSOrder.StopTime;
                        wOrderTimeInfo.StopTime = CalendarUtil.getDayInterval(wOMSOrder.RealReceiveDate.getTime(),
                                Calendar.getInstance().getTime());
                        int wTotalNum =
                                (int) wAPSTaskStepList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.PartID == wPartID).count();
                        wOrderTimeInfo.SurplusNum = wTotalNum - wOrderTimeInfo.FinishNum;
                        wOrderTimeInfo.STTotal =
                                (int) wAPSTaskPartList.stream().filter(p -> p.OrderID == wOMSOrder.ID).count();
                        wOrderTimeInfo.STFinish =
                                (int) wAPSTaskPartList.stream().filter(p -> p.OrderID == wOMSOrder.ID && p.Status == 5).count();
                        wResult.Result.add(wOrderTimeInfo);
                    }
                }
            }

            //移除没有工位的数据
            wResult.Result.removeIf(p -> StringUtils.isEmpty(p.StationName));

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }
}
